www.gusucode.com > VC++仿XP免费Prof UIS界面库-源码程序 > VC++仿XP免费Prof UIS界面库-源码程序/code/Src/ExtPopupMenuWnd.cpp
//Download by http://www.NewXing.com // This is part of the Professional User Interface Suite library. // Copyright (C) 2001-2004 FOSS Software, Inc. // All rights reserved. // // http://www.prof-uis.com // http://www.fossware.com // mailto:foss@fossware.com // // This source code can be used, modified and redistributed // under the terms of the license agreement that is included // in the Professional User Interface Suite package. // // Warranties and Disclaimers: // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND // INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. // IN NO EVENT WILL FOSS SOFTWARE INC. BE LIABLE FOR ANY DIRECT, // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES, // INCLUDING DAMAGES FOR LOSS OF PROFITS, LOSS OR INACCURACY OF DATA, // INCURRED BY ANY PERSON FROM SUCH PERSON'S USAGE OF THIS SOFTWARE // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. // ExtPopupMenuWnd.cpp : implementation file // #include "stdafx.h" #define _AFX_NO_OLE_SUPPORT #ifndef __AFXPRIV_H__ #include <AfxPriv.h> #endif #if _MFC_VER < 0x700 #include <../src/AfxImpl.h> #else #include <../src/mfc/AfxImpl.h> #endif #include <math.h> #if (!defined __EXT_POPUP_MENU_WND_H) #include <ExtPopupMenuWnd.h> #endif #if (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD) #if (!defined __EXT_POPUP_CTRL_MENU_H) #include <ExtPopupCtrlMenu.h> #endif #endif // (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD) #if (!defined __EXT_TOOLCONTROLBAR_H) #include <ExtToolControlBar.h> #endif #if (!defined __EXT_PAINT_MANAGER_H) #include <ExtPaintManager.h> #endif #if (!defined __EXT_MEMORY_DC_H) #include <../Src/ExtMemoryDC.h> #endif #if (!defined __EXT_LOCALIZATION_H) #include <../Src/ExtLocalization.h> #endif #include <../profuisdll/resource.h> #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #if (!defined __EXT_MFC_WINMMDLL_ALREADY_DYN_LIKNED) #define __EXT_MFC_WINMMDLL_ALREADY_DYN_LIKNED #pragma message(" Prof-UIS is automatically linking with WinMM library") #pragma message(" (Windows Multimedia System)") #pragma comment( lib, "winmm.lib" ) #endif #ifdef _DEBUG static int g_nPopupCount = 0; //#define __VPC_VERIFY_0 ASSERT( g_nPopupCount == 0 ) #define __VPC_VERIFY_0 { } #define __VPC_INC g_nPopupCount++ #define __VPC_DEC g_nPopupCount-- #else // _DEBUG #define __VPC_VERIFY_0 { } #define __VPC_INC { } #define __VPC_DEC { } #endif // _DEBUG #define ID_TIMER_ANIMATION 666 #define ID_PERIOD_ANIMATION 30 // 20 #define ID_TIMER_ITEM_FOCUS_DELAY 667 #define ID_PERIOD_ITEM_FOCUS_DELAY 500 #define ID_TIMER_SCROLLING 668 #define ID_PERIOD_SCROLLING 15 #define ID_TIMER_DELAY_SHOW 669 #define ID_PERIOD_DELAY_SHOW 1000 #define ID_TIMER_DELAY_EXPAND 670 #define ID_FREQ_DELAY_EXPAND 50 #define ID_TOTAL_DELAY_EXPAND 1500 #define __SCROLLING_PIXEL_STEP 5 static const int g_nAnimStepMetric = 20; static clock_t g_nLastAnimTime = 0; #define __ANIM_CY 15 #define __EXCLUDE_AREA_GAP_DX 3 #define __EXCLUDE_AREA_GAP_DY __EXCLUDE_AREA_GAP_DX #define __MI_HORZ_GAP_TO_BORDER 1 #define __BOX_ANIM_METRIC 32 // for __AT_BOXES,__AT_CIRCLES animation CExtPopupMenuSite CExtPopupMenuSite::g_DefPopupMenuSite; bool CExtPopupMenuWnd::g_bMenuWithShadows = true; // allow shadows bool CExtPopupMenuWnd::g_bMenuExpanding = true; // allow hide rarely used bool CExtPopupMenuWnd::g_bMenuDelayExpanding = true; // show full menu after short delay bool CExtPopupMenuWnd::g_bMenuHighlightRarely = true; // display rarely used in different style bool CExtPopupMenuWnd::g_bMenuShowCoolTips = true; // allow display cool tooltips bool CExtPopupMenuWnd::g_bMenuExpandAnimation = true; // allow animation when show rarely used bool CExtPopupMenuWnd::g_bUseStretchOnExpandAnimation = false; // use StretchBlt() instead of BitBlt() for painting menu expand amimation bool CExtPopupMenuWnd::g_bMenuLargeIcons = false; // use large icons bool CExtPopupBaseWnd::g_bUseDesktopWorkArea = true; // align to desktop work area (false - to screen area) bool CExtPopupBaseWnd::g_bEnableOnIdleCalls = false; CExtPopupBaseWnd::e_animation_type_t CExtPopupBaseWnd::g_DefAnimationType = CExtPopupBaseWnd::__AT_FADE; // __AT_RANDOM UINT CExtPopupBaseWnd::g_nMsgPrepareMenu = ::RegisterWindowMessage( _T("CExtPopupMenuWnd::g_nMsgPrepareMenu") ); UINT CExtPopupBaseWnd::g_nMsgPopupNext = ::RegisterWindowMessage( _T("CExtPopupMenuWnd::g_nMsgPopupNext") ); UINT CExtPopupBaseWnd::g_nMsgPopupPrev = ::RegisterWindowMessage( _T("CExtPopupMenuWnd::g_nMsgPopupPrev") ); UINT CExtPopupBaseWnd::g_nMsgNotifyMenuExpanded = ::RegisterWindowMessage( _T("CExtPopupMenuWnd::g_nMsgNotifyMenuExpanded") ); UINT CExtPopupBaseWnd::g_nMsgNotifyMenuClosed = ::RegisterWindowMessage( _T("CExtPopupMenuWnd::g_nMsgNotifyMenuClosed") ); UINT CExtPopupBaseWnd::g_nMsgPopupDrawItem = ::RegisterWindowMessage( _T("CExtPopupMenuWnd::g_nMsgPopupDrawItem") ); UINT CExtPopupBaseWnd::g_nMsgPopupDrawLeftArea = ::RegisterWindowMessage( _T("CExtPopupMenuWnd::g_nMsgPopupDrawLeftArea") ); UINT CExtPopupBaseWnd::g_nMsgCreateInplaceEdit = ::RegisterWindowMessage( _T("CExtPopupMenuWnd::g_nMsgCreateInplaceEdit") ); #define __POPUP_WNDCLASS_STYLES__ \ ( CS_SAVEBITS ) // ( CS_SAVEBITS \ // |CS_HREDRAW \ // |CS_VREDRAW \ // |CS_NOCLOSE \ // ) ///////////////////////////////////////////////////////////////////////////// // CExtSoundPlayer CExtSoundPlayer::CExtSoundPlayerAutoPtr g_SoundPlayer; IMPLEMENT_DYNCREATE( CExtSoundPlayer, CObject ); CExtSoundPlayer::InternalSoundEventInitDone_t::InternalSoundEventInitDone_t() : CEvent( FALSE, TRUE ) { } void CExtSoundPlayer::InternalSoundEventInitDone_t::SetInitDone() { SetEvent(); } void CExtSoundPlayer::InternalSoundEventInitDone_t::WaitInitDone() { HANDLE hEvent = *this; ASSERT( hEvent != NULL ); ::WaitForSingleObject( hEvent, INFINITE ); } CExtSoundPlayer::InternalSoundThredadParms_t::InternalSoundThredadParms_t( __EXT_MFC_SAFE_LPCTSTR sSoundSpecBuffer, HANDLE hModule, DWORD dwPlayerFlags ) : m_hModule( hModule ) , m_dwPlayerFlags( dwPlayerFlags ) , m_hThread( NULL ) , m_dwThreadID( 0 ) , m_pEventInitDone( NULL ) { ::memset( m_sSoundSpecBuffer, 0, sizeof(m_sSoundSpecBuffer) ); ASSERT( sSoundSpecBuffer != NULL ); ASSERT( _tclen(sSoundSpecBuffer) > 0 ); _tcsncpy( m_sSoundSpecBuffer, sSoundSpecBuffer, sizeof(m_sSoundSpecBuffer) / sizeof(m_sSoundSpecBuffer[0]) - 1 ); } CEvent CExtSoundPlayer::InternalSoundThredadParms_t::g_EventPlaySnd( TRUE, FALSE, _T("CExtSoundPlayer__InternalSoundThredadParms_t") ); CCriticalSection CExtSoundPlayer::InternalSoundThredadParms_t::g_CsPlaySnd; DWORD WINAPI CExtSoundPlayer::InternalSoundThredadParms_t::stat_ParallelPlayerProc( CExtSoundPlayer::InternalSoundThredadParms_t * pParms ) { ASSERT( pParms != NULL ); pParms->PlaySound(); g_EventPlaySnd.SetEvent(); return 0; } //#define __TRACE_SOUND_PLAYER_THREAD void CExtSoundPlayer::InternalSoundThredadParms_t::PlaySound() { TCHAR sSoundSpecBuffer[ sizeof(m_sSoundSpecBuffer) / sizeof(m_sSoundSpecBuffer[0]) ]; _tcscpy( sSoundSpecBuffer, m_sSoundSpecBuffer ); HANDLE hModule = m_hModule; DWORD dwPlayerFlags = m_dwPlayerFlags; if( m_pEventInitDone != NULL ) m_pEventInitDone->SetInitDone(); #ifdef __TRACE_SOUND_PLAYER_THREAD TRACE1("CExtSoundPlayer::InternalSoundThredadParms_t::PlaySound(\"%s\") - START\n",sSoundSpecBuffer); #endif // __TRACE_SOUND_PLAYER_THREAD if( (m_dwPlayerFlags & SND_ASYNC) != 0 ) ::PlaySound( NULL, NULL, SND_PURGE ); ::PlaySound( sSoundSpecBuffer, (HMODULE)hModule, dwPlayerFlags ); if( (m_dwPlayerFlags & SND_SYNC) != 0 ) ::PlaySound( NULL, NULL, SND_PURGE ); #ifdef __TRACE_SOUND_PLAYER_THREAD TRACE1("CExtSoundPlayer::InternalSoundThredadParms_t::PlaySound(\"%s\") - STOP\n",sSoundSpecBuffer); #endif // __TRACE_SOUND_PLAYER_THREAD } void CExtSoundPlayer::InternalSoundThredadParms_t::PlaySoundParallel() { ASSERT( m_hThread == NULL ); CSingleLock slCs( &g_CsPlaySnd ); slCs.Lock(); HANDLE hEvent = (HANDLE)g_EventPlaySnd; ASSERT( hEvent != NULL ); if( ::WaitForSingleObject(hEvent,0) == WAIT_OBJECT_0 ) { ASSERT( m_pEventInitDone == NULL ); InternalSoundEventInitDone_t EventInitDone; m_pEventInitDone = &EventInitDone; m_hThread = ::CreateThread( NULL, 0, *this, this, CREATE_SUSPENDED, &m_dwThreadID ); ASSERT( m_hThread != NULL ); if( m_hThread != NULL ) { VERIFY( ::SetThreadPriority( m_hThread, THREAD_PRIORITY_BELOW_NORMAL ) ); ::ResumeThread( m_hThread ); EventInitDone.WaitInitDone(); } // if( m_hThread != NULL ) else g_EventPlaySnd.SetEvent(); } // if( ::WaitForSingleObject(hEvent,0) == WAIT_OBJECT_0 ) if( m_hThread != NULL ) ::CloseHandle( m_hThread ); slCs.Unlock(); } CExtSoundPlayer::CExtSoundPlayerAutoPtr::CExtSoundPlayerAutoPtr() { m_pPlayer = new CExtSoundPlayer; } CExtSoundPlayer::CExtSoundPlayerAutoPtr::~CExtSoundPlayerAutoPtr() { if( m_pPlayer != NULL ) delete m_pPlayer; } void CExtSoundPlayer::CExtSoundPlayerAutoPtr::InstallSoundPlayer( CExtSoundPlayer * pPlayer ) { ASSERT( pPlayer != NULL ); ASSERT_VALID( pPlayer ); ASSERT_KINDOF( CExtSoundPlayer, m_pPlayer ); if( m_pPlayer != NULL ) delete m_pPlayer; m_pPlayer = pPlayer; } CExtSoundPlayer::CExtSoundPlayer() { } CExtSoundPlayer::~CExtSoundPlayer() { } void CExtSoundPlayer::PlaySound( CExtSoundPlayer::e_ui_sounds_t eSoundID ) { ASSERT_VALID( this ); switch( eSoundID ) { case __NO_SOUND: return; case __ON_MENU_EXPAND_CLICKED: case __ON_MENU_POPUP_DISPLAYED: { InternalSoundThredadParms_t _istp( _T("MenuPopup"), NULL, SND_ALIAS|SND_NODEFAULT|SND_NOWAIT|SND_ASYNC ); _istp.PlaySoundParallel(); return; } case __ON_MENU_CMD_CLICKED: { InternalSoundThredadParms_t _istp( _T("MenuCommand"), NULL, SND_ALIAS|SND_NODEFAULT|SND_NOWAIT|SND_SYNC ); _istp.PlaySoundParallel(); return; } } // switch( eSoundID ) } ///////////////////////////////////////////////////////////////////////////// // CExtPopupMenuSite CExtPopupMenuSite::CExtPopupMenuSite() : m_pTopMenu( NULL ) , m_pWndCapture( NULL ) , m_pWndAnimation( NULL ) , m_bShutdownMode( false ) , m_hMouseHook( NULL ) , m_hKeyboardHook( NULL ) , m_lpnResultCmdID( NULL ) { } CExtPopupMenuSite::~CExtPopupMenuSite() { _Done(); } CExtPopupMenuWnd * CExtPopupMenuSite::GetCapture() { ASSERT( !IsEmpty() ); ASSERT( !IsShutdownMode() ); return m_pWndCapture; } void CExtPopupMenuSite::SetCapture( CExtPopupMenuWnd * pNewPopup // = NULL ) { ASSERT( !IsEmpty() ); ASSERT( !IsShutdownMode() ); #ifdef _DEBUG if( pNewPopup != NULL ) { ASSERT_VALID( pNewPopup ); } #endif // _DEBUG m_pWndCapture = pNewPopup; } void CExtPopupMenuSite::SetInstance( CExtPopupMenuWnd * pTopMenu // = NULL ) { ASSERT( !IsShutdownMode() ); if( !IsEmpty() ) { ASSERT( m_pTopMenu != NULL ); ASSERT_VALID( m_pTopMenu ); ASSERT( m_pTopMenu->m_bTopLevel ); if( m_pTopMenu == pTopMenu ) return; if( m_pTopMenu != pTopMenu ) _Done(); } ASSERT( m_pTopMenu == NULL ); if( pTopMenu != NULL ) { ASSERT_VALID( pTopMenu ); ASSERT( pTopMenu->m_bTopLevel ); m_pTopMenu = pTopMenu; _Hook( true ); } } CExtPopupMenuWnd * CExtPopupMenuSite::GetAnimated() { ASSERT( !IsEmpty() ); ASSERT( !IsShutdownMode() ); return m_pWndAnimation; } void CExtPopupMenuSite::SetAnimated( CExtPopupMenuWnd * pNewPopup // = NULL ) { ASSERT( !IsEmpty() ); ASSERT( !IsShutdownMode() ); m_pWndAnimation = pNewPopup; } CExtPopupMenuWnd * CExtPopupMenuSite::GetInstance() { return m_pTopMenu; } void CExtPopupMenuSite::SetTargetCmdIdPtr( UINT * lpnResultCmdID // = NULL ) { m_lpnResultCmdID = lpnResultCmdID; } UINT * CExtPopupMenuSite::GetTargetCmdIdPtr() { return m_lpnResultCmdID; } void CExtPopupMenuSite::DoneInstance() { _Done(); } bool CExtPopupMenuSite::IsTopPupup( CExtPopupMenuWnd * pTopMenu ) const { ASSERT( !IsEmpty() ); ASSERT( !IsShutdownMode() ); ASSERT_VALID( pTopMenu ); return (pTopMenu==m_pTopMenu) ? true : false; } void CExtPopupMenuSite::_Done() { ASSERT( !m_bShutdownMode ); m_bShutdownMode = true; m_pWndCapture = NULL; m_pWndAnimation = NULL; m_lpnResultCmdID = NULL; if( m_pTopMenu != NULL ) { ASSERT( m_pTopMenu->m_bTopLevel ); VERIFY( m_pTopMenu->_BuildItems( NULL, true ) ); if( m_pTopMenu->GetSafeHwnd() != NULL && ::IsWindow( m_pTopMenu->GetSafeHwnd() ) ) { CExtControlBar::stat_SetMessageString( m_pTopMenu->GetOwner() ); m_pTopMenu->DestroyWindow(); CExtPopupMenuWnd::PassMsgLoop( CExtPopupBaseWnd::g_bEnableOnIdleCalls ); } ASSERT( m_pTopMenu->GetSafeHwnd() == NULL ); delete m_pTopMenu; m_pTopMenu = NULL; } _Hook( false ); __VPC_VERIFY_0; m_bShutdownMode = false; } LRESULT CALLBACK CExtPopupMenuSite::_HookMouseProc( int nCode, // hook code WPARAM wParam, // message identifier LPARAM lParam // mouse coordinates ) { MOUSEHOOKSTRUCT* lpMS = (MOUSEHOOKSTRUCT*)lParam; ASSERT( lpMS != NULL ); if( !g_DefPopupMenuSite.IsEmpty() && !g_DefPopupMenuSite.IsShutdownMode() ) { CExtPopupMenuWnd * pWndCapture = g_DefPopupMenuSite.GetCapture(); if( pWndCapture != NULL && ::IsWindow( pWndCapture->GetSafeHwnd() ) ) { ASSERT_VALID( pWndCapture ); switch( wParam ) { //case WM_MOUSEACTIVATE: // if( lpMS->hwnd != pWndCapture->GetSafeHwnd() ) // return 1; //break; case WM_MOUSEMOVE: { CPoint pt( lpMS->pt ); pWndCapture->ScreenToClient( &pt ); bool bNoEat = false; if( pWndCapture-> _OnMouseMove( wParam, pt, bNoEat ) ) return 1; // eat! if( bNoEat ) return ::CallNextHookEx( g_DefPopupMenuSite.m_hMouseHook, nCode, wParam, lParam ); } break; case WM_MOUSEWHEEL: { bool bNoEat = false; if( pWndCapture-> _OnMouseWheel( wParam, lParam, bNoEat ) ) return 1; // eat! if( bNoEat ) return ::CallNextHookEx( g_DefPopupMenuSite.m_hMouseHook, nCode, wParam, lParam ); return 1; // eat! } break; case WM_NCLBUTTONDOWN: case WM_NCRBUTTONDOWN: case WM_NCMBUTTONDOWN: case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: case WM_MBUTTONDOWN: case WM_NCLBUTTONUP: case WM_NCRBUTTONUP: case WM_NCMBUTTONUP: case WM_LBUTTONUP: case WM_RBUTTONUP: case WM_MBUTTONUP: { //CRect rcWndCapture; //_pWndCapture->GetWindowRect( &rcWndCapture ); //if( !rcWndCapture.PtInRect(lpMS->pt) ) // break; CPoint ptSrc( lpMS->pt ); pWndCapture->ScreenToClient( &ptSrc ); bool bNoEat = false; if( pWndCapture->_OnMouseClick( wParam, ptSrc, bNoEat ) ) return 1; // eat! if( bNoEat ) return ::CallNextHookEx( g_DefPopupMenuSite.m_hMouseHook, nCode, wParam, lParam ); // post processing CPoint pt( lpMS->pt ); for( CExtPopupMenuWnd * pPopup = pWndCapture; pPopup != NULL; pPopup = pPopup->m_pWndParentMenu ) { CPoint ptClient( pt ); pPopup->ScreenToClient( &ptClient ); if( pPopup->_PtInWndArea(ptClient) ) return 1; // eat! HWND hWndTest = pPopup->m_wndToolTip.GetSafeHwnd(); if( hWndTest != NULL && hWndTest == (::WindowFromPoint(pt)) ) return 1; // eat! } pPopup = CExtPopupMenuSite::g_DefPopupMenuSite.GetInstance(); ASSERT_VALID( pPopup ); ASSERT( ::IsWindow(pPopup->GetSafeHwnd()) ); pPopup->_OnCancelMode(); if( wParam != WM_LBUTTONDOWN && wParam != WM_RBUTTONDOWN && wParam != WM_MBUTTONDOWN ) // currently NC areas are not safe on MDI apps return 1; // eat! } break; //default: // return 1; // eat! } // switch( wParam ) } // if( pWndCapture != NULL .... else return 1; // eat } // if( !g_DefPopupMenuSite.IsEmpty() && !g_DefPopupMenuSite.IsShutdownMode() ) return ::CallNextHookEx( g_DefPopupMenuSite.m_hMouseHook, nCode, wParam, lParam ); } LRESULT CALLBACK CExtPopupMenuSite::_HookKeyboardProc( int nCode, // hook code WPARAM wParam, // virtual-key code LPARAM lParam // keystroke-message information ) { if( !g_DefPopupMenuSite.IsEmpty() && !g_DefPopupMenuSite.IsShutdownMode() ) { CExtPopupMenuWnd * pWndCapture = g_DefPopupMenuSite.GetCapture(); if( pWndCapture->GetSafeHwnd() != NULL && ::IsWindow( pWndCapture->GetSafeHwnd() ) ) { ASSERT_VALID( pWndCapture ); if( (lParam & (1<<31)) == 0 ) { // clocks allows to fix problem with // duplicated fast key hook calls static clock_t _clock_step = CLOCKS_PER_SEC / 50; // 1/50 of second static clock_t _clock_last = 0; //clock(); clock_t _clock_curr = clock(); //ASSERT( _clock_curr >= _clock_last ); clock_t _clock_diff = abs(_clock_curr - _clock_last); if( _clock_diff >= _clock_step ) { _clock_last = _clock_curr; bool bNoEat = false; if( pWndCapture-> _OnKeyDown( wParam, LOWORD(lParam), HIWORD(lParam), bNoEat ) ) return 1; // eat! if( bNoEat ) return ::CallNextHookEx( g_DefPopupMenuSite.m_hKeyboardHook, nCode, wParam, lParam ); if( pWndCapture != NULL ) return 1; // eat! } } // if( (lParam & (1<<31)) == 0 ) else { // 2.21 fix for dlg sys menu return 1; // eat! } } // if( !CExtToolControlBar::g_bMenuTracking ) // return 1; // eat! } // if( !g_DefPopupMenuSite.IsEmpty() && !g_DefPopupMenuSite.IsShutdownMode() ) if( (!CExtToolControlBar::g_bMenuTracking) && CExtPopupMenuWnd::IsCmdKeyActivation( lParam ) && ( lParam & (1<<31) ) != 0 ) { CExtPopupMenuWnd::CancelMenuTracking(); return ::CallNextHookEx( g_DefPopupMenuSite.m_hKeyboardHook, nCode, wParam, lParam ); } return ::CallNextHookEx( g_DefPopupMenuSite.m_hKeyboardHook, nCode, wParam, lParam ); } void CExtPopupMenuSite::_Hook( bool bHook // = true ) { if( bHook ) { if( m_hMouseHook == NULL ) { m_hMouseHook = ::SetWindowsHookEx( WH_MOUSE, _HookMouseProc, 0, ::GetCurrentThreadId() ); ASSERT( m_hMouseHook != NULL ); } if( m_hKeyboardHook == NULL ) { m_hKeyboardHook = ::SetWindowsHookEx( WH_KEYBOARD, _HookKeyboardProc, 0, ::GetCurrentThreadId() ); ASSERT( m_hKeyboardHook != NULL ); } } // if( bHook ) else { if( m_hMouseHook != NULL ) { ::UnhookWindowsHookEx( m_hMouseHook ); m_hMouseHook = NULL; } if( m_hKeyboardHook != NULL ) { ::UnhookWindowsHookEx( m_hKeyboardHook ); m_hKeyboardHook = NULL; } } // else from if( bHook ) } ///////////////////////////////////////////////////////////////////////////// // CExtWndShadow CExtWndShadow::CExtWndShadow() { Destroy(); } CExtWndShadow::~CExtWndShadow() { Destroy(); } void CExtWndShadow::_DoPixelOvershadow( int nMakeSpec, int nPosX, int nPosY, COLORREF clrShadowAdjust ) { ASSERT( nMakeSpec >= 0 && nMakeSpec <= 100 ); ASSERT( !m_rcWndArea.IsRectEmpty() ); ASSERT( nPosX < m_rcWndArea.Width() + INT(m_nShadowSize) ); ASSERT( nPosY < m_rcWndArea.Height() + INT(m_nShadowSize) ); ASSERT( m_pHelperDibSurface != NULL ); int nTotalWidth = m_rcWndArea.Width()+m_nShadowSize; int nTotalHeight = m_rcWndArea.Height()+m_nShadowSize; COLORREF * ptr = m_pHelperDibSurface + nPosX + (nTotalHeight-nPosY)*nTotalWidth; COLORREF clrAdj = *ptr; if( clrShadowAdjust != ((COLORREF)(-1)) ) { int nMakeSpecR = nMakeSpec + ::MulDiv( (100-nMakeSpec), GetBValue(clrShadowAdjust), 255 ); int nMakeSpecG = nMakeSpec + ::MulDiv( (100-nMakeSpec), GetGValue(clrShadowAdjust), 255 ); int nMakeSpecB = nMakeSpec + ::MulDiv( (100-nMakeSpec), GetRValue(clrShadowAdjust), 255 ); if( nMakeSpecR > 100 ) nMakeSpecR = 100; if( nMakeSpecG > 100 ) nMakeSpecG = 100; if( nMakeSpecB > 100 ) nMakeSpecB = 100; clrAdj = RGB( (( nMakeSpecR * int(GetRValue(clrAdj)) ) / 100), (( nMakeSpecG * int(GetGValue(clrAdj)) ) / 100), (( nMakeSpecB * int(GetBValue(clrAdj)) ) / 100) ); } // if( clrShadowAdjust != ((COLORREF)(-1)) ) else { clrAdj = RGB( (( nMakeSpec * int(GetRValue(clrAdj)) ) / 100), (( nMakeSpec * int(GetGValue(clrAdj)) ) / 100), (( nMakeSpec * int(GetBValue(clrAdj)) ) / 100) ); } // else from if( clrShadowAdjust != ((COLORREF)(-1)) ) *ptr = clrAdj; } bool CExtWndShadow::Restore( CDC & dc ) { ASSERT( m_nShadowSize >= 0 ); if( m_nShadowSize == 0 || m_rcWndArea.IsRectEmpty () ) return true; if( m_bmp0.GetSafeHandle() == NULL || m_bmp1.GetSafeHandle() == NULL ) return false; INT nWndAreaDX = m_rcWndArea.Width (); INT nWndAreaDY = m_rcWndArea.Height (); ASSERT( nWndAreaDX > 0 && nWndAreaDY > 0 ); CDC dcmm; if( !dcmm.CreateCompatibleDC(&dc) ) { ASSERT( FALSE ); return false; } CBitmap * pbmpold = dcmm.SelectObject( &m_bmp0 ); ASSERT( pbmpold != NULL ); dc.BitBlt( m_rcWndArea.right, m_rcWndArea.top, m_nShadowSize, nWndAreaDY+m_nShadowSize, &dcmm, 0, 0, SRCCOPY ); dcmm.SelectObject( &m_bmp1 ); dc.BitBlt( m_rcWndArea.left, m_rcWndArea.bottom, nWndAreaDX+m_nShadowSize, m_nShadowSize, &dcmm, 0, 0, SRCCOPY ); dcmm.SelectObject( pbmpold ); return true; } bool CExtWndShadow::Paint( CDC & dc, const CRect & rcWndArea, const CRect & rc1stArea, // = CRect(0,0,0,0) const CRect & rc2ndArea, // = CRect(0,0,0,0) UINT nShadowSize, // = DEF_SHADOW_SIZE UINT nBr0, // = DEF_BRIGHTNESS_MIN UINT nBr1, // = DEF_BRIGHTNESS_MAX bool bEnablePhotos, // = true bool bEnablePaingMgrColor // = true ) { m_rcWndArea = rcWndArea; m_rc1stArea = rc1stArea; m_rc2ndArea = rc2ndArea; m_nShadowSize = nShadowSize; m_nBr0 = nBr0; m_nBr1 = nBr1; m_bEnablePhotos = bEnablePhotos; m_bEnablePaingMgrColor = bEnablePaingMgrColor; return Paint( dc ); } bool CExtWndShadow::Paint( CDC & dc ) { ASSERT( m_nShadowSize >= 0 ); ASSERT( !m_rcWndArea.IsRectEmpty() ); if( m_nShadowSize == 0 || m_rcWndArea.IsRectEmpty() ) return true; if( Restore( dc ) ) return true; if( CExtPaintManager::stat_GetBPP() > 8 ) return _PaintHi( dc ); return _PaintLo( dc ); } bool CExtWndShadow::_PaintLo( CDC & dc ) { INT nWndAreaDX = m_rcWndArea.Width(); INT nWndAreaDY = m_rcWndArea.Height(); ASSERT( m_bmp0.GetSafeHandle() == NULL && m_bmp1.GetSafeHandle() == NULL ); static int _Pattern[] = { ~0xAA, ~0x55, ~0xAA, ~0x55, ~0xAA, ~0x55, ~0xAA, ~0x55 }; CBitmap bmpsh; CBrush brsh; if( !bmpsh.CreateBitmap(8, 8, 1, 1, _Pattern) || !brsh.CreatePatternBrush( &bmpsh ) ) return false; CExtMemoryDC dcmm( &dc, NULL, CExtMemoryDC::MDCOPT_TO_MEMORY ); ASSERT( dcmm.GetSafeHdc() != NULL ); if( dcmm.GetSafeHdc() == NULL ) return false; CPalette * pOldPalette = NULL; if( dcmm.GetDeviceCaps(RASTERCAPS) & RC_PALETTE ) { pOldPalette = dcmm.SelectPalette( &g_PaintManager->m_PaletteWide, FALSE ); dcmm.RealizePalette(); } dcmm.BitBlt( m_rcWndArea.left, m_rcWndArea.top, nWndAreaDX+m_nShadowSize, nWndAreaDY+m_nShadowSize, &dc, m_rcWndArea.left, m_rcWndArea.top, SRCCOPY ); UINT nPaintShadowSize = ( m_nShadowSize > 4 ) ? 4 : m_nShadowSize; CRect rV( m_rcWndArea.right, m_rcWndArea.top+nPaintShadowSize, m_rcWndArea.right+nPaintShadowSize, m_rcWndArea.bottom ); CRect rH( m_rcWndArea.left+nPaintShadowSize, m_rcWndArea.bottom, m_rcWndArea.right+nPaintShadowSize, m_rcWndArea.bottom+nPaintShadowSize ); CBrush * pbrold = dcmm.SelectObject( &brsh ); dcmm.PatBlt( rH.left, rH.top, rH.Width(), rH.Height(), 0xA000C9 ); dcmm.PatBlt( rV.left, rV.top, rV.Width(), rV.Height(), 0xA000C9 ); dcmm.SelectObject( pbrold ); dc.BitBlt( m_rcWndArea.left, m_rcWndArea.top, nWndAreaDX+m_nShadowSize, nWndAreaDY+m_nShadowSize, &dcmm, m_rcWndArea.left, m_rcWndArea.top, SRCCOPY ); if( m_bEnablePhotos ) { if( !_MakePhotos(dc,dcmm) ) { ASSERT( FALSE ); return false; } } if( pOldPalette != NULL ) dcmm.SelectPalette( pOldPalette, FALSE ); dcmm.__Flush( FALSE ); return true; } bool CExtWndShadow::_PaintHi( CDC & dc ) { INT nWndAreaDX = m_rcWndArea.Width(); INT nWndAreaDY = m_rcWndArea.Height(); ASSERT( m_bmp0.GetSafeHandle() == NULL && m_bmp1.GetSafeHandle() == NULL ); CDC dcmm; if( !dcmm.CreateCompatibleDC( &dc ) ) { ASSERT( FALSE ); return false; } COLORREF clrShadowAdjust = ((COLORREF)(-1)); if( m_bEnablePaingMgrColor ) clrShadowAdjust = g_PaintManager->GetShadowAdjustColor(); BITMAPINFOHEADER bih; bih.biSize = sizeof(BITMAPINFOHEADER); bih.biWidth = nWndAreaDX+m_nShadowSize; bih.biHeight = nWndAreaDY+m_nShadowSize; bih.biPlanes = 1; bih.biBitCount = 32; bih.biCompression = BI_RGB; bih.biSizeImage = (nWndAreaDX+m_nShadowSize) * (nWndAreaDY+m_nShadowSize); bih.biXPelsPerMeter = 0; bih.biYPelsPerMeter = 0; bih.biClrUsed = 0; bih.biClrImportant = 0; ASSERT( m_pHelperDibSurface == NULL ); HBITMAP hDIB = ::CreateDIBSection( dcmm.GetSafeHdc(), (LPBITMAPINFO)&bih, DIB_RGB_COLORS, (void **)&m_pHelperDibSurface, NULL, NULL ); if( hDIB == NULL || m_pHelperDibSurface == NULL ) { ASSERT( FALSE ); return false; } dcmm.SelectObject( hDIB ); dcmm.BitBlt( 0, 0, nWndAreaDX+m_nShadowSize, nWndAreaDY+m_nShadowSize, &dc, m_rcWndArea.left, m_rcWndArea.top, SRCCOPY ); UINT nBrDiff = m_nBr1-m_nBr0; LONG n2nd, nStep, nDist, nDist1; LONG nDist2 = m_nShadowSize*m_nShadowSize; INT nMakeSpec; bool bCmbaV = false, bCmbaH = false, bCmbaVrt = false, bCmbaVrb = false, bCmbaHrb = false, bCmbaHlb = false, bCmbaLA = false; INT nX0 = 0, nX1 = nWndAreaDX, nY0 = 0, nY1 = nWndAreaDY, nLa0 = 0, nLa1 = 0; if( !( m_rc1stArea.IsRectEmpty() || m_rc2ndArea.IsRectEmpty() ) ) { bool bCmbaDetected = false; if( m_rc1stArea.right == m_rc2ndArea.right ) { // vertical-right combining bCmbaDetected = true; if( m_rc1stArea.top < m_rc2ndArea.top ) bCmbaVrb = true; else bCmbaVrt = true; } // vertical-right combining if( (!bCmbaDetected) && m_rc1stArea.left == m_rc2ndArea.left ) { // vertical-left combining if( m_rc2ndArea.bottom >= m_rc1stArea.top-1 && m_rc2ndArea.top < m_rc1stArea.top ) { if( m_rc2ndArea.right >= m_rc1stArea.right ) { bCmbaDetected = true; bCmbaV = true; } } if( (!bCmbaDetected) && m_rc1stArea.bottom >= m_rc2ndArea.top-1 && m_rc1stArea.top < m_rc2ndArea.top ) { if( m_rc1stArea.right >= m_rc2ndArea.right ) { bCmbaDetected = true; bCmbaH = true; nX0 = m_rcWndArea.right - (m_rc1stArea.right - m_rc2ndArea.right); } } } // vertical-left combining if( (!bCmbaDetected) && m_rc1stArea.bottom == m_rc2ndArea.bottom ) { // horizontal-bottom combining bCmbaDetected = true; if( m_rc1stArea.left < m_rc2ndArea.left ) bCmbaHrb = true; else bCmbaHlb = true; } // horizontal-bottom combining if( (!bCmbaDetected) && m_rc1stArea.right == m_rc2ndArea.left+1 ) { bCmbaDetected = true; bCmbaLA = true; nLa0 = m_rcWndArea.top + m_rc2ndArea.bottom - m_rc1stArea.top; nLa1 = nLa0 + m_nShadowSize; } if( (!bCmbaDetected) && m_rc1stArea.left == m_rc2ndArea.right-1 ) { bCmbaDetected = true; bCmbaH = true; } bCmbaDetected; } // if( !( m_rc1stArea.IsRectEmpty() || m_rc2ndArea.IsRectEmpty() ) ) for( nStep = 0; ULONG(nStep) < m_nShadowSize; nStep++ ) { nMakeSpec = m_nBr0+(nStep*nBrDiff)/m_nShadowSize; for( n2nd = nX0 + m_nShadowSize*2+1 - ( bCmbaH ? (m_nShadowSize*2-nStep) : 0 ) - ( bCmbaHlb ? m_nShadowSize : 0 ) ; n2nd < LONG(nX1) + (bCmbaHrb ? LONG(m_nShadowSize) : 0); n2nd++ ) _DoPixelOvershadow( nMakeSpec, n2nd, nY1 + nStep, clrShadowAdjust ); for( n2nd = nY0 + m_nShadowSize*2+1 - ( bCmbaV ? (m_nShadowSize*2-nStep) : 0 ) - ( bCmbaVrt ? m_nShadowSize : 0 ) ; n2nd < LONG(nY1) + (bCmbaVrb ? LONG(m_nShadowSize) : 0); n2nd++ ) { if( bCmbaLA && n2nd >= nLa0 && n2nd < LONG(nLa1) - (LONG(m_nShadowSize) - nStep) ) { continue; } _DoPixelOvershadow( nMakeSpec, nX1 + nStep, n2nd, clrShadowAdjust ); } nDist1 = nStep*nStep; for( n2nd = 0; ULONG(n2nd) < m_nShadowSize; n2nd++ ) { nDist = nDist1 + n2nd*n2nd; if( nDist > nDist2 ) continue; nDist = (LONG)::sqrt( double(nDist) ); nMakeSpec = m_nBr0+(nDist*nBrDiff)/m_nShadowSize; if( !(bCmbaVrb || bCmbaHrb) ) _DoPixelOvershadow( nMakeSpec, nX1+nStep, nY1+n2nd, clrShadowAdjust ); if( !(bCmbaH || bCmbaHlb) ) _DoPixelOvershadow( nMakeSpec, m_nShadowSize+(m_nShadowSize-nStep), nY1 + n2nd, clrShadowAdjust ); if( !(bCmbaV || bCmbaVrt) ) _DoPixelOvershadow( nMakeSpec, nX1 + nStep, m_nShadowSize+(m_nShadowSize-n2nd), clrShadowAdjust ); } // for( n2nd = 0; ULONG(n2nd) < m_nShadowSize; n2nd++ ) } // for( nStep = 0; ULONG(nStep) < m_nShadowSize; nStep++ ) dc.BitBlt( m_rcWndArea.left, m_rcWndArea.top, nWndAreaDX+m_nShadowSize, nWndAreaDY+m_nShadowSize, &dcmm, 0, 0, SRCCOPY ); if( m_bEnablePhotos ) { if( !_MakePhotos(dc,dcmm) ) { ASSERT( FALSE ); return false; } } ::DeleteObject( hDIB ); m_pHelperDibSurface = NULL; return true; } bool CExtWndShadow::_MakePhotos( CDC & dc, CDC & dcmm ) { ASSERT( m_nShadowSize >= 0 ); ASSERT( !m_rcWndArea.IsRectEmpty() ); INT nWndAreaDX = m_rcWndArea.Width(); INT nWndAreaDY = m_rcWndArea.Height(); ASSERT( m_bmp0.GetSafeHandle() == NULL && m_bmp1.GetSafeHandle() == NULL ); if( !m_bmp0.CreateCompatibleBitmap( &dc, m_nShadowSize, nWndAreaDY+m_nShadowSize ) ) { ASSERT( FALSE ); return false; } dcmm.SelectObject( &m_bmp0 ); if( !dcmm.BitBlt( 0, 0, m_nShadowSize, nWndAreaDY+m_nShadowSize, &dc, m_rcWndArea.right, m_rcWndArea.top, SRCCOPY ) ) { ASSERT( FALSE ); return false; } if( !m_bmp1.CreateCompatibleBitmap( &dc, nWndAreaDX+m_nShadowSize, m_nShadowSize ) ) { ASSERT( FALSE ); return false; } dcmm.SelectObject( &m_bmp1 ); if( !dcmm.BitBlt( 0, 0, nWndAreaDX+m_nShadowSize, m_nShadowSize, &dc, m_rcWndArea.left, m_rcWndArea.bottom, SRCCOPY ) ) { ASSERT( FALSE ); return false; } return true; } void CExtWndShadow::_FreeWinObjects() { if( m_bmp0.GetSafeHandle() != NULL ) m_bmp0.DeleteObject(); if( m_bmp1.GetSafeHandle() != NULL ) m_bmp1.DeleteObject(); m_pHelperDibSurface = NULL; } void CExtWndShadow::Destroy() { _FreeWinObjects(); m_rcWndArea.SetRectEmpty(); m_bEnablePhotos = false; m_bEnablePaingMgrColor = false; } ///////////////////////////////////////////////////////////////////////////// // CExtPopupMenuWnd::MENUITEMDATA CExtPopupMenuWnd::MENUITEMDATA::MENUITEMDATA() : m_cAccelChar( _T('\0') ) { // self constant type assertion ASSERT( TYPE_SEPARATOR==ID_SEPARATOR ); m_pWndChild = NULL; m_nItemIndex = -100; m_nCmdID = TYPE_SEPARATOR; #if (!defined __EXT_MFC_NO_CUSTOMIZE) m_pCmdNode = NULL; #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) m_sItemText = m_sAccelText = _T(""); m_sizeItem.cx = m_sizeItem.cy = 0; m_nIconAreaWidth = 0; m_bSelected = m_bDisplayed = m_bForceDisplayed = m_bChildCombine = m_bToolButton = m_bForceEnabled = m_bForceNoLeftGradient = m_bCheck = m_bRadio = m_bIndeterminate = m_bXtraChecked = m_bNoCmdUI = false; m_pCbCmdDeliver = NULL; m_pCbXtraMarkState = NULL; m_bEnabled = true; m_hWndSpecCmdReciever = NULL; m_pHelperInplaceEditWnd = NULL; m_pInplaceEditStr = NULL; m_pCbVerifyTextInput = NULL; m_pCbPutTextInputResult = NULL; m_pInplaceEditCbWndProc = NULL; m_pInplaceEditCbCoockie = NULL; m_nInplaceEditWidth = 0; m_bAllowInplaceEditActivation = true; m_nLParam = 0L; m_bTempSelTextValid = false; m_sTempSelText.Empty(); } CExtPopupMenuWnd::MENUITEMDATA::MENUITEMDATA( const CExtPopupMenuWnd::MENUITEMDATA & other ) : m_cAccelChar( _T('\0') ) { // self constant type assertion ASSERT( TYPE_SEPARATOR==ID_SEPARATOR ); m_pWndChild = NULL; m_nItemIndex = -100; m_nCmdID = TYPE_SEPARATOR; #if (!defined __EXT_MFC_NO_CUSTOMIZE) m_pCmdNode = NULL; #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) m_sItemText = m_sAccelText = _T(""); m_sizeItem.cx = m_sizeItem.cy = 0; m_nIconAreaWidth = 0; m_bSelected = m_bDisplayed = m_bForceDisplayed = m_bChildCombine = m_bToolButton = m_bForceEnabled = m_bForceNoLeftGradient = m_bCheck = m_bRadio = m_bIndeterminate = m_bXtraChecked = m_bNoCmdUI = false; m_pCbCmdDeliver = NULL; m_pCbXtraMarkState = NULL; m_bEnabled = true; m_hWndSpecCmdReciever = NULL; m_pHelperInplaceEditWnd = NULL; m_pInplaceEditStr = NULL; m_pCbVerifyTextInput = NULL; m_pCbPutTextInputResult = NULL; m_pInplaceEditCbWndProc = NULL; m_pInplaceEditCbCoockie = NULL; m_nInplaceEditWidth = 0; m_bAllowInplaceEditActivation = true; m_nLParam = 0L; m_bTempSelTextValid = false; m_sTempSelText.Empty(); AssignFromOther( other ); } CExtPopupMenuWnd::MENUITEMDATA::~MENUITEMDATA() { // DestroyPopup(); } CExtPopupMenuWnd::MENUITEMDATA & CExtPopupMenuWnd::MENUITEMDATA::operator=( const CExtPopupMenuWnd::MENUITEMDATA & other ) { AssignFromOther( other ); return (*this); } void CExtPopupMenuWnd::MENUITEMDATA::AssignFromOther( const CExtPopupMenuWnd::MENUITEMDATA & other ) { // self constant type assertion ASSERT( TYPE_SEPARATOR==ID_SEPARATOR ); LPVOID lpvThis = (LPVOID)this; LPVOID lpvOther = (LPVOID)(&other); if( lpvThis == lpvOther ) return; m_pWndChild = other.m_pWndChild; m_nItemIndex = other.m_nItemIndex; m_nCmdID = other.m_nCmdID; #if (!defined __EXT_MFC_NO_CUSTOMIZE) m_pCmdNode = other.m_pCmdNode; #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) m_sItemText = other.m_sItemText; m_sAccelText = other.m_sAccelText; m_iconPopup = other.m_iconPopup; m_sizeItem = other.m_sizeItem; m_nIconAreaWidth = other.m_nIconAreaWidth; m_bSelected = other.m_bSelected; m_bDisplayed = other.m_bDisplayed; m_bForceDisplayed = other.m_bForceDisplayed; m_bChildCombine = other.m_bChildCombine; m_bToolButton = other.m_bToolButton; m_bForceEnabled = other.m_bForceEnabled; m_bForceNoLeftGradient = other.m_bForceNoLeftGradient; m_cAccelChar = other.m_cAccelChar; m_hWndSpecCmdReciever = other.m_hWndSpecCmdReciever; m_bCheck = other.m_bCheck; m_bRadio = other.m_bRadio; m_pCbCmdDeliver = other.m_pCbCmdDeliver; m_pCbXtraMarkState = other.m_pCbXtraMarkState; m_bXtraChecked = other.m_bXtraChecked; m_bNoCmdUI = other.m_bNoCmdUI; m_bEnabled = other.m_bEnabled; m_bIndeterminate = other.m_bIndeterminate; m_pHelperInplaceEditWnd = other.m_pHelperInplaceEditWnd; m_pInplaceEditStr = other.m_pInplaceEditStr; m_pCbVerifyTextInput = other.m_pCbVerifyTextInput; m_pCbPutTextInputResult = other.m_pCbPutTextInputResult; m_pInplaceEditCbWndProc = other.m_pInplaceEditCbWndProc; m_pInplaceEditCbCoockie = other.m_pInplaceEditCbCoockie; m_nInplaceEditWidth = other.m_nInplaceEditWidth; m_bAllowInplaceEditActivation = other.m_bAllowInplaceEditActivation; m_nLParam = other.m_nLParam; m_bTempSelTextValid = other.m_bTempSelTextValid; m_sTempSelText = other.m_sTempSelText; } CRect CExtPopupMenuWnd::MENUITEMDATA::AdjustInplaceEditRect( const RECT & rcItem ) const { CRect rcInplaceEdit( rcItem ); int nInplaceEditWidth = GetInplaceEditWidth(); ASSERT( nInplaceEditWidth > 0 ); rcInplaceEdit.DeflateRect( 1, 2, 1, 2 + __EXT_MENU_VERT_DISTANCE_NORM ); rcInplaceEdit.left = rcInplaceEdit.right - nInplaceEditWidth; if( IsPopup() ) // rcInplaceEdit.OffsetRect( // - ::GetSystemMetrics(SM_CXHTHUMB), // 0 // ); rcInplaceEdit.right -= ::GetSystemMetrics(SM_CXHTHUMB); return rcInplaceEdit; } UINT CExtPopupMenuWnd::MENUITEMDATA::GetCmdID() const { if( IsSeparator() || IsPopup() ) return ( (UINT) (IDC_STATIC) ); return m_nCmdID; } UINT CExtPopupMenuWnd::MENUITEMDATA::SetCmdID( UINT nCmdID ) { // should be used only without references to command manager ASSERT( ! IsPopup() ); // should not be applied for popups UINT nOldCmdID = m_nCmdID; m_nCmdID = nCmdID; return nOldCmdID; } bool CExtPopupMenuWnd::MENUITEMDATA::SetPopupText( __EXT_MFC_SAFE_LPCTSTR strText ) { SetText( strText ); int nPos = m_sItemText.Find(_T('\t')); if( nPos >= 0 ) { CExtSafeString sLeft = m_sItemText.Left(nPos); CExtSafeString sRight = m_sItemText.Right(m_sItemText.GetLength()-nPos-1); m_sItemText = sLeft; m_sAccelText = sRight; } return true; } bool CExtPopupMenuWnd::MENUITEMDATA::SetPopupAccelText( __EXT_MFC_SAFE_LPCTSTR strText ) // NULL if empty { m_sAccelText = (strText == NULL) ? _T("") : strText; return true; } __EXT_MFC_SAFE_LPCTSTR CExtPopupMenuWnd::MENUITEMDATA::GetText() const { if( IsSeparator() ) return _T(""); return m_sItemText; } void CExtPopupMenuWnd::MENUITEMDATA::SetText( __EXT_MFC_SAFE_LPCTSTR strText ) { if( IsSeparator() ) return; m_sItemText = (strText != NULL) ? strText : _T(""); } __EXT_MFC_SAFE_LPCTSTR CExtPopupMenuWnd::MENUITEMDATA::GetAccelText() const { if( IsSeparator() ) return _T(""); return m_sAccelText; } void CExtPopupMenuWnd::MENUITEMDATA::SetAccelText( __EXT_MFC_SAFE_LPCTSTR strText ) { if( IsSeparator() ) return; m_sAccelText = (strText != NULL) ? strText : _T(""); } void CExtPopupMenuWnd::MENUITEMDATA::AccelCharInit() { m_cAccelChar = _T('\0'); CExtSafeString sDisplayText( GetText() ); if( sDisplayText.IsEmpty() ) return; int nIndex = sDisplayText.Find( _T('&') ); if( nIndex + 1 == sDisplayText.GetLength() ) { TRACE(_T("warning : & is bad position, access key is invalid.\n")); return; } if( nIndex < 0 ) { if( !CExtPopupMenuWnd::g_bAllowNonAccelPositioning ) return; m_cAccelChar = sDisplayText[0]; } else m_cAccelChar = sDisplayText[nIndex + 1]; // -1 + 1 = 0; it's ok TCHAR szChar[2] = { m_cAccelChar, _T('\0') }; ::CharUpper( szChar ); m_cAccelChar = szChar[0]; } __EXT_MFC_SAFE_TCHAR CExtPopupMenuWnd::MENUITEMDATA::AccelCharGet() const { return __EXT_MFC_SAFE_TCHAR( m_cAccelChar ); } bool CExtPopupMenuWnd::MENUITEMDATA::AccelCharIsSet() const { return (m_cAccelChar == _T('\0') ) ? false : true; } bool CExtPopupMenuWnd::MENUITEMDATA::UpdateCmdManagerCommand( CExtCmdItem * pCmdItem, int nItemIndex ) { ASSERT( pCmdItem != NULL ); ASSERT( !IsPopup() ); ASSERT( m_pWndChild == NULL ); m_sItemText.Empty(); m_sAccelText.Empty(); m_nCmdID = pCmdItem->m_nCmdID; if( !CExtCmdManager::IsCommand(m_nCmdID) ) { m_nCmdID = TYPE_SEPARATOR; m_nItemIndex = -100; ASSERT( FALSE ); return false; } if( nItemIndex >= 0 ) m_nItemIndex = nItemIndex; SetText( pCmdItem->m_sMenuText ); SetAccelText( pCmdItem->m_sAccelText ); AccelCharInit(); MeasureItem(); return true; } CExtCmdItem * CExtPopupMenuWnd::MENUITEMDATA::GetCmd() const { if( IsSeparator() || IsNoCmdUI() ) return NULL; #if (!defined __EXT_MFC_NO_CUSTOMIZE) CExtCustomizeCmdTreeNode * pNode = ((MENUITEMDATA*)this)->GetCmdNode(); if( pNode != NULL && ( (pNode->GetFlags() & __ECTN_TBB_COLOR) != NULL || IsInplaceEdit() ) ) { CExtCmdItem * pCmdItem = g_CmdManager->CmdGetPtr( g_CmdManager->ProfileNameFromWnd( GetCmdReciever() ), pNode->GetCmdID( false ) ); ASSERT( pCmdItem != NULL ); return pCmdItem; } // if( pNode != NULL ... #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) if( IsPopup() ) return NULL; CExtCmdItem * pCmdItem = g_CmdManager->CmdGetPtr( g_CmdManager->ProfileNameFromWnd( GetCmdReciever() ), m_nCmdID ); //ASSERT( pCmdItem != NULL ); return pCmdItem; } #if (!defined __EXT_MFC_NO_CUSTOMIZE) CExtCustomizeCmdTreeNode * CExtPopupMenuWnd::MENUITEMDATA::GetCmdNode() { #ifdef _DEBUG if( m_pCmdNode != NULL ) { ASSERT_VALID( m_pCmdNode ); } #endif // _DEBUG return m_pCmdNode; } #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) void CExtPopupMenuWnd::MENUITEMDATA::MeasureItem() { AccelCharInit(); m_nIconAreaWidth = __EXT_MENU_ICON_CX; if( IsSeparator() ) { m_sizeItem.cx = 0; m_sizeItem.cy = __EXT_MENU_SEPARATOR_HEIGHT; return; } CExtSafeString sMeasureText( GetText() ); if( !IsInplaceEdit() ) sMeasureText += (LPCTSTR)GetAccelText(); sMeasureText.Replace( _T("&"), _T("") ); CWindowDC dc(NULL); CFont * pOldFont = dc.SelectObject( &(g_PaintManager->m_FontNormal) ); ASSERT( pOldFont != NULL ); CRect rect( 0, 0, 0, 0 ); ::DrawText( dc.GetSafeHdc(), sMeasureText, sMeasureText.GetLength(), &rect, DT_CALCRECT|DT_SINGLELINE|DT_LEFT ); m_sizeItem.cx = rect.Width(); m_sizeItem.cy = rect.Height() + __EXT_MENU_IMG_RECT_OUT_GAP*2; dc.SelectObject( pOldFont ); CSize sizeIcon( 0, 0 ); int nIconHeightMetric = 0; if( !IsToolButton() ) { CExtCmdIcon * pIcon = GetIconPtr(); if( pIcon != NULL ) { sizeIcon = pIcon->GetSize(); if( g_bMenuLargeIcons ) { sizeIcon.cx *= 2; sizeIcon.cy *= 2; } // if( g_bMenuLargeIcons ) if( sizeIcon.cx < __EXT_MENU_ICON_CX ) sizeIcon.cx = __EXT_MENU_ICON_CX; if( sizeIcon.cy < __EXT_MENU_ICON_CY ) sizeIcon.cy = __EXT_MENU_ICON_CY; if( sizeIcon.cx <= 18 && sizeIcon.cy < sizeIcon.cx ) sizeIcon.cy = sizeIcon.cx; m_nIconAreaWidth = max( m_nIconAreaWidth, sizeIcon.cx ); nIconHeightMetric = sizeIcon.cy + __EXT_MENU_IMG_RECT_OUT_GAP*2; } // if( pIcon != NULL ) } // if( !IsToolButton() ) m_sizeItem.cy = max( m_sizeItem.cy, nIconHeightMetric ); if( m_sizeItem.cy < __EXT_MENU_MIN_HEIGHT ) m_sizeItem.cy = __EXT_MENU_MIN_HEIGHT; if( IsToolButton() && sizeIcon.cy == 0 ) m_sizeItem.cy -= 2; m_nIconAreaWidth = max( sizeIcon.cx, m_sizeItem.cy ); if( IsExtraMark() ) { m_nIconAreaWidth *= 2; m_nIconAreaWidth += 4; } // if( IsExtraMark() ) m_sizeItem.cx += __EXT_MENU_GAP * 7; if( IsInplaceEdit() ) { m_sizeItem.cx += m_nInplaceEditWidth + 2 + 10; // if( IsPopup() ) // m_sizeItem.cx += ::GetSystemMetrics(SM_CXHTHUMB); } // if( IsInplaceEdit() ) else if( IsToolButton() ) { m_sizeItem.cx += __DROPDOWN_ARROW_GAP * 2 + __EXT_MENU_TOOLBTN_GAP * 2; m_sizeItem.cy += __EXT_MENU_VERT_DISTANCE_NORM; } // if( IsToolButton() ) else { m_sizeItem.cx += m_nIconAreaWidth // sizeIcon.cx + __EXT_MENU_POPUP_ARROW_AREA_DX; m_sizeItem.cy += __EXT_MENU_VERT_DISTANCE_TOOL; } // else from if( IsToolButton() ) } bool CExtPopupMenuWnd::MENUITEMDATA::UpdateFromMenu( HWND hWndCmdProfileInfo, CMenu * pTrackMenu, int nItemIndex ) { ASSERT( pTrackMenu != NULL ); ASSERT( pTrackMenu->GetSafeHmenu() != NULL ); #ifdef _DEBUG int nMenuItemCount = pTrackMenu->GetMenuItemCount(); ASSERT( nMenuItemCount > 0 ); ASSERT( nItemIndex >= 0 && nItemIndex<nMenuItemCount ); #endif // _DEBUG MENUITEMINFO _mii; ::memset( &_mii, 0, sizeof(MENUITEMINFO) ); _mii.cbSize = sizeof(MENUITEMINFO); _mii.fMask = MIIM_CHECKMARKS |MIIM_DATA |MIIM_ID |MIIM_STATE |MIIM_SUBMENU |MIIM_TYPE ; _mii.cch = __MAX_UI_ITEM_TEXT; CExtSafeString _sItemText; _mii.dwTypeData = _sItemText.GetBuffer(__MAX_UI_ITEM_TEXT); ASSERT( _mii.dwTypeData != NULL ); if( _mii.dwTypeData == NULL ) { ASSERT( FALSE ); return false; } if( !pTrackMenu->GetMenuItemInfo( nItemIndex, &_mii, TRUE ) ) { _sItemText.ReleaseBuffer(); ASSERT( FALSE ); return false; } _sItemText.ReleaseBuffer(); m_nItemIndex = nItemIndex; if( (_mii.fType&MFT_SEPARATOR) != 0 ) { m_sItemText.Empty(); m_nCmdID = TYPE_SEPARATOR; MeasureItem(); return true; } if( _mii.hSubMenu != NULL ) { if( !ConstructPopup() ) { ASSERT( FALSE ); return false; } m_nCmdID = (UINT)TYPE_POPUP; SetPopupText( _sItemText ); MeasureItem(); return true; } // m_sItemText.Empty(); if( !CExtCmdManager::IsCommand(_mii.wID) ) { ASSERT( FALSE ); return false; } m_nCmdID = _mii.wID; CExtCmdItem * pCmdItem = g_CmdManager->CmdGetPtr( g_CmdManager->ProfileNameFromWnd( hWndCmdProfileInfo ), m_nCmdID ); ASSERT( pCmdItem != NULL ); if( pCmdItem == NULL ) return false; if( _sItemText.IsEmpty() ) _sItemText = pCmdItem->m_sMenuText; if( _sItemText.IsEmpty() ) _sItemText = pCmdItem->m_sToolbarText; SetPopupText( _sItemText ); MeasureItem(); return true; } #if (!defined __EXT_MFC_NO_CUSTOMIZE) #if (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD) bool CExtPopupMenuWnd::MENUITEMDATA::stat_CbVerifyTextInput( CInPlaceEditWnd & wndEdit, CExtCustomizeCmdTreeNode * pNode, __EXT_MFC_SAFE_LPCTSTR sTextOld, __EXT_MFC_SAFE_LPCTSTR sTextNew ) { ASSERT_VALID( pNode ); ASSERT( sTextOld != NULL ); ASSERT( sTextNew != NULL ); ASSERT( wndEdit.GetSafeHwnd() != NULL && ::IsWindow( wndEdit.GetSafeHwnd() ) ); CExtCustomizeSite * pSite = CExtCustomizeSite::GetCustomizeSite( wndEdit.GetSafeHwnd() ); if( pSite == NULL ) return true; return pSite->OnTextFieldVerify( NULL, pNode, sTextOld, sTextNew ); } void CExtPopupMenuWnd::MENUITEMDATA::stat_CbPutTextInputResult( CInPlaceEditWnd & wndEdit, CExtCustomizeCmdTreeNode * pNode, __EXT_MFC_SAFE_LPCTSTR sTextNew ) { ASSERT_VALID( pNode ); ASSERT( sTextNew != NULL ); ASSERT( wndEdit.GetSafeHwnd() != NULL && ::IsWindow( wndEdit.GetSafeHwnd() ) ); CExtCustomizeSite * pSite = CExtCustomizeSite::GetCustomizeSite( wndEdit.GetSafeHwnd() ); if( pSite == NULL ) return; pSite->OnTextFieldInplaceTextSet( NULL, pNode, pNode->m_sDefInplaceEditBuffer, sTextNew ); } bool CExtPopupMenuWnd::MENUITEMDATA::stat_CbInplaceEditWndProc( LRESULT & lResult, UINT message, WPARAM wParam, LPARAM lParam, CEdit & wndEdit, CExtCustomizeCmdTreeNode * pNode ) { if( message == CExtCustomizeSite::g_nMsgQueryCustomizeSite ) return false; if( (wndEdit.GetStyle() & WS_VISIBLE) == 0 ) return false; ASSERT_VALID( pNode ); ASSERT( wndEdit.GetSafeHwnd() != NULL && ::IsWindow( wndEdit.GetSafeHwnd() ) ); CExtCustomizeSite * pSite = CExtCustomizeSite::GetCustomizeSite( wndEdit.GetSafeHwnd() ); if( pSite == NULL ) return false; return pSite->OnTextFieldWndProcHook( lResult, message, wParam, lParam, wndEdit, NULL, pNode ); } bool CExtPopupMenuWnd::MENUITEMDATA::stat_CbInitListBoxContent( CExtPopupInplaceListBox & wndListBox, CExtCustomizeCmdTreeNode * pNode ) { ASSERT_VALID( pNode ); ASSERT( wndListBox.GetSafeHwnd() != NULL && ::IsWindow( wndListBox.GetSafeHwnd() ) ); CExtCustomizeSite * pSite = CExtCustomizeSite::GetCustomizeSite( wndListBox.GetSafeHwnd() ); if( pSite == NULL ) return false; return pSite->OnPopupListBoxInitContent( NULL, pNode, wndListBox ); } bool CExtPopupMenuWnd::MENUITEMDATA::stat_CbListBoxSelection( CExtPopupInplaceListBox & wndListBox, CExtCustomizeCmdTreeNode * pNode, int eSAT // CExtPopupInplaceListBox::e_sel_action_t ) { ASSERT_VALID( pNode ); ASSERT( wndListBox.GetSafeHwnd() != NULL && ::IsWindow( wndListBox.GetSafeHwnd() ) ); CExtCustomizeSite * pSite = CExtCustomizeSite::GetCustomizeSite( wndListBox.GetSafeHwnd() ); if( pSite == NULL ) return false; switch( ((CExtPopupInplaceListBox::e_sel_action_t)eSAT) ) { case CExtPopupInplaceListBox::e_sel_action_t::__SAT_SELCHANGE: return pSite->OnPopupListBoxSelChange( NULL, pNode, wndListBox ); case CExtPopupInplaceListBox::e_sel_action_t::__SAT_SELENDOK: return pSite->OnPopupListBoxSelEndOK( NULL, pNode, wndListBox ); case CExtPopupInplaceListBox::e_sel_action_t::__SAT_SELENDCANCEL: return pSite->OnPopupListBoxSelEndCancel( NULL, pNode, wndListBox ); #ifdef _DEBUG default: ASSERT( FALSE ); break; #endif // _DEBUG } // switch( ((CExtPopupInplaceListBox::e_sel_action_t)eSAT) ) return false; } bool CExtPopupMenuWnd::MENUITEMDATA::stat_CbListBoxItemDraw( CExtPopupInplaceListBox & wndListBox, CExtCustomizeCmdTreeNode * pNode, LPDRAWITEMSTRUCT pDIS ) { ASSERT_VALID( pNode ); ASSERT( pDIS != NULL && pDIS->hDC != NULL ); ASSERT( wndListBox.GetSafeHwnd() != NULL && ::IsWindow( wndListBox.GetSafeHwnd() ) ); CExtCustomizeSite * pSite = CExtCustomizeSite::GetCustomizeSite( wndListBox.GetSafeHwnd() ); if( pSite == NULL ) return false; if( pSite->OnPopupListBoxItemDraw( NULL, pNode, wndListBox, pDIS ) ) return true; if( (wndListBox.GetStyle() & LBS_HASSTRINGS) == 0 ) return false; if( ((INT)pDIS->itemID) < 0 || ((INT)pDIS->itemID) >= wndListBox.GetCount() ) return true; CDC dc; dc.Attach( pDIS->hDC ); dc.FillSolidRect( &pDIS->rcItem, g_PaintManager->GetColor( ( pDIS->itemState & ODS_SELECTED ) ? COLOR_HIGHLIGHT : COLOR_WINDOW ) ); CString sText; wndListBox.GetText( (INT)pDIS->itemID, sText ); if( !sText.IsEmpty() ) { COLORREF clrTextOld = dc.SetTextColor( g_PaintManager->GetColor( ( pDIS->itemState & ODS_SELECTED ) ? COLOR_HIGHLIGHTTEXT : COLOR_BTNTEXT ) ); int nOldBkMode = dc.SetBkMode( TRANSPARENT ); CRect rcText( pDIS->rcItem ); rcText.DeflateRect( pSite->OnPopupListBoxCalcItemExtraSizes( NULL, pNode ) ); dc.DrawText( sText, &rcText, DT_SINGLELINE|DT_LEFT|DT_VCENTER|DT_NOPREFIX ); dc.SetBkMode( nOldBkMode ); dc.SetTextColor( clrTextOld ); } // if( !sText.IsEmpty() ) if( pDIS->itemState & ODS_SELECTED ) dc.DrawFocusRect( &pDIS->rcItem ); dc.Detach(); return true; } bool CExtPopupMenuWnd::MENUITEMDATA::stat_CbListBoxItemMeasure( CExtPopupInplaceListBox & wndListBox, CExtCustomizeCmdTreeNode * pNode, LPMEASUREITEMSTRUCT pMIS ) { ASSERT_VALID( pNode ); ASSERT( pMIS != NULL ); ASSERT( wndListBox.GetSafeHwnd() != NULL && ::IsWindow( wndListBox.GetSafeHwnd() ) ); CExtCustomizeSite * pSite = CExtCustomizeSite::GetCustomizeSite( wndListBox.GetSafeHwnd() ); if( pSite == NULL ) return false; if( pSite->OnPopupListBoxItemMeasure( NULL, pNode, wndListBox, pMIS ) ) return true; if( (wndListBox.GetStyle() & LBS_HASSTRINGS) == 0 ) return false; pMIS->itemWidth = pMIS->itemHeight = 10; if( ((INT)pMIS->itemID) < 0 || ((INT)pMIS->itemID) >= wndListBox.GetCount() ) return true; CExtSafeString sMeasure; wndListBox.GetText( (INT)pMIS->itemID, *((CString*)&sMeasure) ); if( sMeasure.IsEmpty() ) return true; CWindowDC dc( NULL ); CRect rcMeasure = CExtPaintManager::stat_CalcTextDimension( dc, g_PaintManager->m_FontNormal, sMeasure ); rcMeasure.InflateRect( pSite->OnPopupListBoxCalcItemExtraSizes( NULL, pNode ) ); pMIS->itemWidth = rcMeasure.Width(); pMIS->itemHeight = rcMeasure.Height(); return true; } #endif // (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD) bool CExtPopupMenuWnd::MENUITEMDATA::UpdateFromCmdTree( HWND hWndCmdRecv, CExtCustomizeCmdTreeNode * pNode, int nItemIndex ) { ASSERT_VALID( pNode ); m_nItemIndex = nItemIndex; CExtCustomizeSite * pSite = NULL; #if (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD) if( (pNode->GetFlags() & __ECTN_TBB_TEXT_FIELD) != 0 ) { ASSERT( m_hWndSpecCmdReciever != NULL ); ASSERT( ::IsWindow(m_hWndSpecCmdReciever) ); pSite = CExtCustomizeSite::GetCustomizeSite( m_hWndSpecCmdReciever ); if( pSite == NULL ) { ASSERT( FALSE ); return false; } bool bComboField = ( (pNode->GetFlags() & __ECTN_TBB_COMBO) != 0 ) ? true : false; m_nCmdID = bComboField ? ((UINT)TYPE_POPUP) : pNode->GetCmdID( false ) ; m_pCmdNode = pNode; if( bComboField ) { // construct a popup ASSERT( m_iconPopup.IsEmpty() ); ASSERT( m_pWndChild == NULL ); CExtPopupControlMenuWnd * pExtCrtPopup = pSite->OnTextFieldCreateDropPopup( NULL, pNode, m_hWndSpecCmdReciever, false ); if( pExtCrtPopup != NULL ) { m_pWndChild = pExtCrtPopup; } // if( pExtCrtPopup != NULL ) else { CExtPopupListBoxMenuWnd * pPopup = new CExtPopupListBoxMenuWnd; pPopup->m_lParamListCookie = pNode->GetLParam(); pPopup->m_pCbListBoxSelection = (CExtPopupInplaceListBox::pCbListBoxSelection) stat_CbListBoxSelection; pPopup->m_pSelectionCoockie = (LPVOID)pNode; pPopup->m_pCbInitListBoxContent = (CExtPopupInplaceListBox::pCbInitListBoxContent) stat_CbInitListBoxContent; pPopup->m_pInitListBoxCoockie = (LPVOID)pNode; pPopup->m_pCbListBoxItemDraw = (CExtPopupInplaceListBox::pCbListBoxItemDraw) stat_CbListBoxItemDraw; pPopup->m_pCbListBoxItemMeasure = (CExtPopupInplaceListBox::pCbListBoxItemMeasure) stat_CbListBoxItemMeasure; pPopup->m_pListBoxItemCoockie = (LPVOID)pNode; pSite->OnPopupListBoxGetStyles( NULL, pNode, pPopup->m_dwListBoxStyles ); CSize sizeMeasure = pSite->OnPopupListBoxMeasureTrackSize( NULL, pNode ); if( sizeMeasure.cx == 0 && sizeMeasure.cy == 0 ) { pPopup->m_sizeChildControl.cx = pNode->TextFieldWidthGet() //+ ::GetSystemMetrics( SM_CXHTHUMB ) ; pPopup->m_sizeChildControl.cy = pNode->DropDownHeightMaxGet(); } // if( sizeMeasure.cx == 0 && sizeMeasure.cy == 0 ) else pPopup->m_sizeChildControl = sizeMeasure; m_pWndChild = pPopup; } // else from if( pExtCrtPopup != NULL ) m_pWndChild->m_hWndCmdReciever = m_hWndSpecCmdReciever; // m_sItemText = _T(""); m_sAccelText = _T(""); SetPopupText( pNode->GetTextInMenu( NULL ) ); } // if( bComboField ) else m_sItemText = pNode->GetTextInMenu( NULL ); pSite->OnTextFieldInplaceTextGet( NULL, pNode, pNode->m_sDefInplaceEditBuffer ); SetInplaceEdit( &pNode->m_sDefInplaceEditBuffer, (CExtPopupMenuWnd::pCbVerifyTextInput)stat_CbVerifyTextInput, (CExtPopupMenuWnd::pCbPutTextInputResult)stat_CbPutTextInputResult, (CExtPopupMenuWnd::pCbInplaceEditWndProc)stat_CbInplaceEditWndProc, (LPVOID)pNode, pNode->TextFieldWidthGet() ); SetDisplayed( true ); MeasureItem(); return true; } // if( (pNode->GetFlags() & __ECTN_TBB_TEXT_FIELD) != 0 ) #endif // (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD) if( pNode->GetFlags() & __ECTN_TBB_COLOR ) { ASSERT( m_iconPopup.IsEmpty() ); ASSERT( m_pWndChild == NULL ); CExtPopupColorMenuWnd * pColorPopup= new CExtPopupColorMenuWnd; m_pWndChild = pColorPopup; ASSERT( m_hWndSpecCmdReciever != NULL ); ASSERT( ::IsWindow(m_hWndSpecCmdReciever) ); m_pWndChild->m_hWndCmdReciever = m_hWndSpecCmdReciever; m_nCmdID = (UINT)TYPE_POPUP; m_sItemText = pNode->GetTextInMenu( NULL ); m_pCmdNode = pNode; ASSERT( m_pWndChild != NULL ); m_pWndChild->m_pNode = pNode; pColorPopup->m_lParamCookie = pNode->GetLParam(); pColorPopup->m_bEnableBtnColorDefault = ( (pNode->GetFlags() & __ECTN_TBB_MCB_DEFAULT) != 0 ) ? true : false; pColorPopup->m_bEnableBtnColorCustom = ( (pNode->GetFlags() & __ECTN_TBB_MCB_CUSTOM) != 0 ) ? true : false; if( pSite == NULL ) pSite = CExtCustomizeSite::GetCustomizeSite( m_hWndSpecCmdReciever ); if( pSite == NULL ) { ASSERT( FALSE ); return false; } pSite->OnColorItemValueGet( NULL, pNode, pColorPopup->m_clrDefault, false ); pSite->OnColorItemValueGet( NULL, pNode, pColorPopup->m_clrInitial, true ); CExtSafeString sBtnText; if( pSite->OnColorItemGetBtnTextDefault( NULL, pNode, sBtnText ) ) pColorPopup->m_sBtnTextColorDefault = sBtnText; sBtnText.Empty(); if( pSite->OnColorItemGetBtnTextCustom( NULL, pNode, sBtnText ) ) pColorPopup->m_sBtnTextColorCustom = sBtnText; HICON hIconColorItem = pSite->OnColorItemGenerateIcon( NULL, pNode, pColorPopup->m_clrInitial ); if( hIconColorItem != NULL ) m_iconPopup.AssignFromHICON( hIconColorItem, false ); MeasureItem(); return true; } // if( pNode->GetFlags() & __ECTN_TBB_COLOR ) if( (pNode->GetFlags() & __ECTN_AUTO_POPUP) != 0 || pNode->GetNodeCount() > 0 ) { if( !ConstructPopup() ) { ASSERT( FALSE ); return false; } m_nCmdID = (UINT)TYPE_POPUP; m_sItemText = pNode->GetTextInMenu( NULL ); m_pCmdNode = pNode; ASSERT( m_pWndChild != NULL ); m_pWndChild->m_pNode = pNode; MeasureItem(); return true; } // m_sItemText.Empty(); if( !CExtCmdManager::IsCommand(pNode->GetCmdID()) ) { ASSERT( FALSE ); return false; } #if (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD) if( (pNode->GetFlags() & (__ECTN_TBB_COMBO|__ECTN_TBB_TEXT_FIELD) ) == 0 ) #endif // (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD) m_nCmdID = pNode->GetCmdID(); CExtCmdItem * pCmdItem = g_CmdManager->CmdGetPtr( g_CmdManager->ProfileNameFromWnd( hWndCmdRecv ), pNode->GetCmdID() ); ASSERT( pCmdItem != NULL ); if( pCmdItem == NULL ) return false; m_sItemText = pNode->GetTextInMenu( pCmdItem ); m_pCmdNode = pNode; MeasureItem(); return true; } #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) ///////////////////////////////////////////////////////////////////////////// // CExtPopupBaseWnd IMPLEMENT_DYNCREATE(CExtPopupBaseWnd, __BaseClassOfCExtPopupBaseWnd) CExtPopupBaseWnd::CExtPopupBaseWnd() { m_clrFadeBitsSrc = m_clrFadeBitsDst = m_clrFadeBitsTmp = NULL; m_AnimationType = g_DefAnimationType; _InitAnimation(); m_ePlaySoundOnAnimationFinished = CExtSoundPlayer::__NO_SOUND; m_sizeFullItems.cx = m_sizeFullItems.cy = 1; m_bExcludeAreaSpec = m_bCombineWithEA = false; m_rcExcludeArea.SetRectEmpty(); m_ptTrack.x = m_ptTrack.y; } CExtPopupBaseWnd::~CExtPopupBaseWnd() { } void CExtPopupBaseWnd::_AdjustAnimation( CExtPopupBaseWnd::e_animation_type_t & eAT ) { ASSERT_VALID( this ); eAT; } void CExtPopupBaseWnd::_InitAnimation() { ASSERT_VALID( this ); m_nAnimPercent = m_nAnimPercentOld = 0; //m_AnimationType = g_DefAnimationType; _AdjustAnimation( m_AnimationType ); if( (m_AnimationType < 0 || m_AnimationType > __AT_MAX_VALID_VALUE) && m_AnimationType != __AT_CONTENT_DISPLAY && m_AnimationType != __AT_CONTENT_EXPAND ) m_AnimationType = __AT_NONE; if( m_AnimationType == __AT_RANDOM ) { int nRand = rand() % (__AT_MAX_VALID_VALUE+1); ASSERT( nRand >= 0 && nRand <= __AT_MAX_VALID_VALUE ); if( nRand == __AT_NONE || nRand == __AT_RANDOM ) nRand = __AT_FADE; // most cool of all effects m_AnimationType = (e_animation_type_t)nRand; } int nBitsPerPixel = CExtPaintManager::stat_GetBPP(); if( nBitsPerPixel <= 8 && m_AnimationType != __AT_CONTENT_EXPAND && m_AnimationType != __AT_CONTENT_DISPLAY ) { m_AnimationType = __AT_NONE; m_bAnimFinished = true; } else { m_bAnimFinished = (m_AnimationType == __AT_NONE) ? true : false; } ASSERT( m_bmpScreenDst.GetSafeHandle() == NULL && m_bmpScreenSrc.GetSafeHandle() == NULL && m_bmpScreenTmp.GetSafeHandle() == NULL && m_clrFadeBitsSrc == NULL && m_clrFadeBitsDst == NULL && m_clrFadeBitsTmp == NULL ); } void CExtPopupBaseWnd::_StartAnimation() { ASSERT_VALID( this ); _InitAnimation(); if( m_AnimationType != __AT_NONE ) { SetTimer( ID_TIMER_ANIMATION, ID_PERIOD_ANIMATION, NULL ); g_nLastAnimTime = clock(); } } void CExtPopupMenuWnd::_StartAnimation() { ASSERT_VALID( this ); if( _FindCustomizeMode() ) return; _ItemFocusDelay(); _CoolTipHide( false ); CExtPopupBaseWnd::_StartAnimation(); GetSite().SetAnimated( m_bAnimFinished ? NULL : this ); } BEGIN_MESSAGE_MAP(CExtPopupBaseWnd, __BaseClassOfCExtPopupBaseWnd) //{{AFX_MSG_MAP(CExtPopupBaseWnd) ON_WM_MOUSEACTIVATE() ON_WM_ERASEBKGND() ON_WM_PAINT() ON_WM_NCPAINT() ON_WM_NCCALCSIZE() ON_WM_SIZE() ON_WM_ACTIVATEAPP() ON_WM_CANCELMODE() ON_WM_SETCURSOR() ON_WM_TIMER() //}}AFX_MSG_MAP END_MESSAGE_MAP() void CExtPopupBaseWnd::OnPaint() { ASSERT_VALID( this ); if( !(::IsWindow(GetSafeHwnd())) ) return; if( !(::IsWindowVisible(GetSafeHwnd())) ) return; CPaintDC dc(this); // device context for painting CExtPaintManager::stat_ExcludeChildAreas( dc.GetSafeHdc(), m_hWnd ); if( !m_bAnimFinished ) _DrawAnimatedState( dc ); else _DoPaint( dc ); } void CExtPopupBaseWnd::_DrawAnimatedState( CDC & dc ) { ASSERT_VALID( this ); _DoPaint( dc ); } void CExtPopupMenuWnd::_DrawAnimatedState( CDC & dc ) { ASSERT_VALID( this ); if( !(::IsWindow(GetSafeHwnd())) ) return; CRect rcClient; GetClientRect( &rcClient ); int cx = rcClient.Width(); int cy = rcClient.Height(); CDC * pPaintDC = &dc; CPalette * pOldPalette = NULL; if( pPaintDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE ) { pOldPalette = pPaintDC->SelectPalette( &g_PaintManager->m_PaletteWide, FALSE ); pPaintDC->RealizePalette(); } CDC dcmm; VERIFY( dcmm.CreateCompatibleDC(pPaintDC) ); bool bFail = false; if( m_bmpScreenDst.GetSafeHandle() == NULL ) { ASSERT( m_bmpScreenSrc.GetSafeHandle() == NULL ); ASSERT( m_bmpScreenTmp.GetSafeHandle() == NULL ); int nBitsPerPixel = CExtPaintManager::stat_GetBPP(); CBitmap * pBmpOld = NULL; if( (m_AnimationType == __AT_FADE && nBitsPerPixel > 8 ) || m_AnimationType == __AT_CONTENT_EXPAND || m_AnimationType == __AT_CONTENT_DISPLAY || m_AnimationType == __AT_ROLL || m_AnimationType == __AT_SLIDE || m_AnimationType == __AT_ROLL_AND_STRETCH || m_AnimationType == __AT_SLIDE_AND_STRETCH || m_AnimationType == __AT_NOISE || m_AnimationType == __AT_BOXES || m_AnimationType == __AT_CIRCLES || m_AnimationType == __AT_HOLES ) { BITMAPINFOHEADER bih; bih.biSize = sizeof(BITMAPINFOHEADER); bih.biWidth = cx; bih.biHeight = cy; bih.biPlanes = 1; bih.biBitCount = 32; bih.biCompression = BI_RGB; bih.biSizeImage = cx * cy; bih.biXPelsPerMeter = 0; bih.biYPelsPerMeter = 0; bih.biClrUsed = 0; bih.biClrImportant = 0; HBITMAP hDIB = ::CreateDIBSection( dcmm.GetSafeHdc(), (LPBITMAPINFO)&bih, DIB_RGB_COLORS, (void **)&m_clrFadeBitsSrc, NULL, NULL ); if( hDIB != NULL && m_clrFadeBitsSrc != NULL ) { m_bmpScreenSrc.Attach( hDIB ); hDIB = ::CreateDIBSection( dcmm.GetSafeHdc(), (LPBITMAPINFO)&bih, DIB_RGB_COLORS, (void **)&m_clrFadeBitsDst, NULL, NULL ); if( hDIB != NULL && m_clrFadeBitsDst != NULL ) { m_bmpScreenDst.Attach( hDIB ); hDIB = ::CreateDIBSection( dcmm.GetSafeHdc(), (LPBITMAPINFO)&bih, DIB_RGB_COLORS, (void **)&m_clrFadeBitsTmp, NULL, NULL ); if( hDIB != NULL && m_clrFadeBitsTmp != NULL ) { m_bmpScreenTmp.Attach( hDIB ); pBmpOld = dcmm.SelectObject( &m_bmpScreenSrc ); dcmm.BitBlt( 0, 0, cx, cy, pPaintDC, rcClient.left, rcClient.top, SRCCOPY ); ::memcpy( m_clrFadeBitsDst, m_clrFadeBitsSrc, sizeof(COLORREF)*cx*cy ); dcmm.SelectObject( &m_bmpScreenDst ); } // if( hDIB != NULL && m_clrFadeBitsTmp != NULL ) else { m_bmpScreenSrc.DeleteObject(); m_bmpScreenDst.DeleteObject(); //return; bFail = true; } // else from if( hDIB != NULL && m_clrFadeBitsTmp != NULL ) } // if( hDIB != NULL && m_clrFadeBitsDst != NULL ) else { m_bmpScreenSrc.DeleteObject(); //return; bFail = true; } // else from if( hDIB != NULL && m_clrFadeBitsDst != NULL ) } // if( hDIB != NULL && m_clrFadeBitsSrc != NULL ) } else { m_bmpScreenDst.CreateCompatibleBitmap( pPaintDC, cx, cy ); pBmpOld = dcmm.SelectObject( &m_bmpScreenDst ); } if( !bFail ) _DoPaint( dcmm, false ); dcmm.SetViewportOrg( CPoint(0,0) ); dcmm.SelectObject( pBmpOld ); } // if( m_bmpScreenDst.GetSafeHandle() == NULL ) CBitmap * pBmpOld = NULL; if( !bFail ) { COLORREF * src = m_clrFadeBitsSrc; COLORREF * dst = m_clrFadeBitsDst; COLORREF * tmp = m_clrFadeBitsTmp; switch( m_AnimationType ) { case __AT_BOXES: case __AT_CIRCLES: case __AT_HOLES: if( tmp!= NULL && src!=NULL && dst != NULL ) { ASSERT( m_nAnimPercent >= 0 && m_nAnimPercent <= 100 && m_nAnimPercentOld >= 0 && m_nAnimPercentOld <= 100 && m_nAnimPercentOld <= m_nAnimPercent ); ASSERT( __BOX_ANIM_METRIC > 0 ); // self assert if( m_nAnimPercentOld != m_nAnimPercent ) { pBmpOld = dcmm.SelectObject( &m_bmpScreenTmp ); if( m_AnimationType == __AT_BOXES ) { // do boxes animation for( int y=0; y<cy; y++ ) { int _y0 = y % __BOX_ANIM_METRIC; int _yPercent = 100 - (_y0 * 100) / __BOX_ANIM_METRIC; if( _yPercent < m_nAnimPercent ) { ::memcpy( tmp, src, cx*sizeof(COLORREF) ); tmp += cx; src += cx; dst += cx; continue; } for( int x=0; x<cx; x++ ) { int _x0 = x % __BOX_ANIM_METRIC; int _xPercent = (_x0 * 100) / __BOX_ANIM_METRIC; if( _xPercent < m_nAnimPercent ) *tmp = *dst; else *tmp = *src; tmp++; src++; dst++; } } // for( int y=0; y<cy; y++ ) } // do boxes animation else { // do circles/holes animation double radius = 0; if( m_AnimationType == __AT_HOLES ) radius = ((((double)(__BOX_ANIM_METRIC)) / 2) * (100-m_nAnimPercent)) / 100; else radius = ((((double)(__BOX_ANIM_METRIC)) / 2) * m_nAnimPercent) / 100; if( radius > 0 ) { for( int y=0; y<cy; y++ ) { int _y0 = y % __BOX_ANIM_METRIC; int _y1 = y - _y0; //int _y2 = _y1 + __BOX_ANIM_METRIC; int _yCenter = _y1 + __BOX_ANIM_METRIC/2; int _yDist = abs( y - _yCenter ); double _yDist2 = (double)_yDist*_yDist; for( int x=0; x<cx; x++ ) { int _x0 = x % __BOX_ANIM_METRIC; int _x1 = x - _x0; //int _x2 = _x1 + __BOX_ANIM_METRIC; int _xCenter = _x1 + __BOX_ANIM_METRIC/2; int _xDist = abs( x - _xCenter ); double _xDist2 = (double)_xDist*_xDist; double nDispance = ::sqrt(_yDist2+_xDist2); if( m_AnimationType == __AT_HOLES ) { // holes if( nDispance >= radius ) *tmp = *dst; else *tmp = *src; } // holes else { // circles if( nDispance < radius ) *tmp = *dst; else *tmp = *src; } // circles tmp++; src++; dst++; } } // for( int y=0; y<cy; y++ ) } // if( radius > 0 ) } // do circles/holes animation int nMenuShadowSize = _GetPopupShadowSize(); if( m_bCombineWithEA ) { // paint combined area AS IS ASSERT( !m_rcExcludeArea.IsRectEmpty() ); CRect rcExcludeArea( m_rcExcludeArea ); ScreenToClient( &rcExcludeArea ); pBmpOld = dcmm.SelectObject( &m_bmpScreenDst ); pPaintDC->BitBlt( rcExcludeArea.left, rcExcludeArea.top, rcExcludeArea.Width(), rcExcludeArea.Height(), &dcmm, rcExcludeArea.left, rcExcludeArea.top, SRCCOPY ); dcmm.SelectObject( pBmpOld ); pBmpOld = NULL; if( m_eCombineAlign != __CMBA_NONE ) { // int nMenuShadowSize = _GetPopupShadowSize(); rcExcludeArea.InflateRect( (m_eCombineAlign == __CMBA_RIGHT) ? 0 : nMenuShadowSize, (m_eCombineAlign == __CMBA_BOTTOM) ? 0 : nMenuShadowSize, (m_eCombineAlign == __CMBA_LEFT) ? 0 : nMenuShadowSize, (m_eCombineAlign == __CMBA_TOP) ? 0 : nMenuShadowSize ); } // if( m_eCombineAlign != __CMBA_NONE ) pPaintDC->ExcludeClipRect( &rcExcludeArea ); } // paint combined area AS IS if( nMenuShadowSize > 0 ) { CRect rcExcludeArea( rcClient ); rcExcludeArea.left = rcExcludeArea.right - nMenuShadowSize; pPaintDC->ExcludeClipRect( &rcExcludeArea ); rcExcludeArea = rcClient ; rcExcludeArea.top = rcExcludeArea.bottom - nMenuShadowSize; pPaintDC->ExcludeClipRect( &rcExcludeArea ); } pPaintDC->BitBlt( rcClient.left, rcClient.top, cx, cy, &dcmm, 0, 0, SRCCOPY ); if( nMenuShadowSize > 0 || m_bCombineWithEA ) pPaintDC->SelectClipRgn( NULL ); } // if( m_nAnimPercentOld != m_nAnimPercent ) } break; // cases __AT_BOXES,__AT_CIRCLES,__AT_HOLES case __AT_NOISE: if( tmp!= NULL && src!=NULL && dst != NULL ) { ASSERT( m_nAnimPercent >= 0 && m_nAnimPercent <= 100 && m_nAnimPercentOld >= 0 && m_nAnimPercentOld <= 100 && m_nAnimPercentOld <= m_nAnimPercent ); if( m_nAnimPercentOld != m_nAnimPercent ) { int nDiff = m_nAnimPercent - m_nAnimPercentOld; ASSERT( nDiff > 0 ); int nRandHalf = nDiff / 2 + 1; ASSERT( nRandHalf > 0 ); pBmpOld = dcmm.SelectObject( &m_bmpScreenTmp ); for( int pixel = 0; pixel < cx * cy; pixel++ ) { int nRandValue = rand() % nDiff; if( nRandValue > nRandHalf ) *tmp = *dst; // else // *tmp = *src; tmp++; src++; dst++; } // for( int pixel = 0; pixel < cx * cy; pixel++ ) int nMenuShadowSize = _GetPopupShadowSize(); if( m_bCombineWithEA ) { // paint combined area AS IS ASSERT( !m_rcExcludeArea.IsRectEmpty() ); CRect rcExcludeArea( m_rcExcludeArea ); ScreenToClient( &rcExcludeArea ); pBmpOld = dcmm.SelectObject( &m_bmpScreenDst ); pPaintDC->BitBlt( rcExcludeArea.left, rcExcludeArea.top, rcExcludeArea.Width(), rcExcludeArea.Height(), &dcmm, rcExcludeArea.left, rcExcludeArea.top, SRCCOPY ); dcmm.SelectObject( pBmpOld ); pBmpOld = NULL; if( m_eCombineAlign != __CMBA_NONE ) { // int nMenuShadowSize = _GetPopupShadowSize(); rcExcludeArea.InflateRect( (m_eCombineAlign == __CMBA_RIGHT) ? 0 : nMenuShadowSize, (m_eCombineAlign == __CMBA_BOTTOM) ? 0 : nMenuShadowSize, (m_eCombineAlign == __CMBA_LEFT) ? 0 : nMenuShadowSize, (m_eCombineAlign == __CMBA_TOP) ? 0 : nMenuShadowSize ); } // if( m_eCombineAlign != __CMBA_NONE ) pPaintDC->ExcludeClipRect( &rcExcludeArea ); } // paint combined area AS IS if( nMenuShadowSize > 0 ) { CRect rcExcludeArea( rcClient ); rcExcludeArea.left = rcExcludeArea.right - nMenuShadowSize; pPaintDC->ExcludeClipRect( &rcExcludeArea ); rcExcludeArea = rcClient ; rcExcludeArea.top = rcExcludeArea.bottom - nMenuShadowSize; pPaintDC->ExcludeClipRect( &rcExcludeArea ); } pPaintDC->BitBlt( rcClient.left, rcClient.top, cx, cy, &dcmm, 0, 0, SRCCOPY ); if( nMenuShadowSize > 0 || m_bCombineWithEA ) pPaintDC->SelectClipRgn( NULL ); } // if( m_nAnimPercentOld != m_nAnimPercent ) } break; // case __AT_NOISE case __AT_SLIDE: case __AT_ROLL: case __AT_ROLL_AND_STRETCH: case __AT_SLIDE_AND_STRETCH: if( tmp!= NULL && src!=NULL && dst != NULL ) { ASSERT( m_nAnimPercent >= 0 && m_nAnimPercent <= 100 && m_nAnimPercentOld >= 0 && m_nAnimPercentOld <= 100 && m_nAnimPercentOld <= m_nAnimPercent ); CRect _rcClient; _GetClientRect( &_rcClient ); if( m_bCombineWithEA ) { // paint combined area AS IS ASSERT( !m_rcExcludeArea.IsRectEmpty() ); CRect rcExcludeArea( m_rcExcludeArea ); ScreenToClient( &rcExcludeArea ); pBmpOld = dcmm.SelectObject( &m_bmpScreenDst ); pPaintDC->BitBlt( rcExcludeArea.left, rcExcludeArea.top, rcExcludeArea.Width(), rcExcludeArea.Height(), &dcmm, rcExcludeArea.left, rcExcludeArea.top, SRCCOPY ); dcmm.SelectObject( pBmpOld ); pBmpOld = NULL; if( m_eCombineAlign != __CMBA_NONE ) { int nMenuShadowSize = _GetPopupShadowSize(); rcExcludeArea.InflateRect( (m_eCombineAlign == __CMBA_RIGHT) ? 0 : nMenuShadowSize, (m_eCombineAlign == __CMBA_BOTTOM) ? 0 : nMenuShadowSize, (m_eCombineAlign == __CMBA_LEFT) ? 0 : nMenuShadowSize, (m_eCombineAlign == __CMBA_TOP) ? 0 : nMenuShadowSize ); } // if( m_eCombineAlign != __CMBA_NONE ) pPaintDC->ExcludeClipRect( &rcExcludeArea ); } // paint combined area AS IS pBmpOld = dcmm.SelectObject( &m_bmpScreenDst ); int cx = _rcClient.Width(); int cy = _rcClient.Height(); if( m_AnimationType == __AT_ROLL || m_AnimationType == __AT_SLIDE ) { // non-stratchable variants int _cx = 0; if( m_AnimationType == __AT_ROLL ) _cx = (cx * (100-m_nAnimPercent)) / 100; int _cy = (cy * (100-m_nAnimPercent)) / 100; if( m_eCombineAlign == __CMBA_RIGHT ) { CRgn rgnClip; if( rgnClip.CreateRectRgnIndirect( &_rcClient ) ) pPaintDC->SelectClipRgn( &rgnClip ); pPaintDC->BitBlt( _rcClient.left+_cx, _rcClient.top-_cy, cx, cy, &dcmm, _rcClient.left, _rcClient.top, SRCCOPY ); pPaintDC->SelectClipRgn( NULL ); } // if m_eCombineAlign is __CMBA_RIGHT else if( m_eCombineAlign == __CMBA_BOTTOM ) { CRgn rgnClip; if( rgnClip.CreateRectRgnIndirect( &_rcClient ) ) pPaintDC->SelectClipRgn( &rgnClip ); pPaintDC->BitBlt( _rcClient.left-_cx, _rcClient.top+_cy, cx, cy, &dcmm, _rcClient.left, _rcClient.top, SRCCOPY ); pPaintDC->SelectClipRgn( NULL ); } // if m_eCombineAlign is __CMBA_BOTTOM else { // if m_eCombineAlign is __CMBA_TOP or __CMBA_LEFT pPaintDC->BitBlt( _rcClient.left-_cx, _rcClient.top-_cy, cx, cy, &dcmm, _rcClient.left, _rcClient.top, SRCCOPY ); } // if m_eCombineAlign is __CMBA_TOP or __CMBA_LEFT } // non-stratchable variants else { // stratchable variants int _cx = cx; if( m_AnimationType == __AT_ROLL_AND_STRETCH ) _cx = (cx * m_nAnimPercent) / 100; int _cy = (cy * m_nAnimPercent) / 100; int nOldStretchBltMode = pPaintDC->SetStretchBltMode( g_PaintManager.m_bIsWinNT ? HALFTONE : COLORONCOLOR ); if( m_eCombineAlign == __CMBA_RIGHT && m_AnimationType == __AT_ROLL_AND_STRETCH ) { CRgn rgnClip; if( rgnClip.CreateRectRgnIndirect( &_rcClient ) ) pPaintDC->SelectClipRgn( &rgnClip ); pPaintDC->StretchBlt( _rcClient.left+cx-_cx, _rcClient.top, _cx, _cy, &dcmm, _rcClient.left, _rcClient.top, cx, cy, SRCCOPY ); pPaintDC->SelectClipRgn( NULL ); } // if m_eCombineAlign is __CMBA_RIGHT with __AT_ROLL_AND_STRETCH animation else if( m_eCombineAlign == __CMBA_BOTTOM ) { CRgn rgnClip; if( rgnClip.CreateRectRgnIndirect( &_rcClient ) ) pPaintDC->SelectClipRgn( &rgnClip ); pPaintDC->StretchBlt( _rcClient.left-cx+_cx, _rcClient.top+cy-_cy, _cx, _cy, &dcmm, _rcClient.left, _rcClient.top, cx, cy, SRCCOPY ); pPaintDC->SelectClipRgn( NULL ); } // if m_eCombineAlign is __CMBA_BOTTOM else { // if m_eCombineAlign is __CMBA_TOP or __CMBA_LEFT pPaintDC->StretchBlt( _rcClient.left, _rcClient.top, _cx, _cy, &dcmm, _rcClient.left, _rcClient.top, cx, cy, SRCCOPY ); } // if m_eCombineAlign is __CMBA_TOP or __CMBA_LEFT pPaintDC->SetStretchBltMode( nOldStretchBltMode ); } // stratchable variants if( m_bCombineWithEA ) pPaintDC->SelectClipRgn( NULL ); } break; // cases __AT_ROLL, __AT_SLIDE, __AT_ROLL_AND_STRETCH, __AT_ROLL_AND_STRETCH case __AT_CONTENT_EXPAND: if( tmp!= NULL && src!=NULL && dst != NULL ) { ASSERT( m_nAnimPercent >= 0 && m_nAnimPercent <= 100 && m_nAnimPercentOld >= 0 && m_nAnimPercentOld <= 100 && m_nAnimPercentOld <= m_nAnimPercent ); CRect _rcClient; _GetClientRect( &_rcClient ); if( m_bCombineWithEA ) { // paint combined area AS IS ASSERT( !m_rcExcludeArea.IsRectEmpty() ); CRect rcExcludeArea( m_rcExcludeArea ); ScreenToClient( &rcExcludeArea ); pBmpOld = dcmm.SelectObject( &m_bmpScreenDst ); pPaintDC->BitBlt( rcExcludeArea.left, rcExcludeArea.top, rcExcludeArea.Width(), rcExcludeArea.Height(), &dcmm, rcExcludeArea.left, rcExcludeArea.top, SRCCOPY ); dcmm.SelectObject( pBmpOld ); pBmpOld = NULL; } // paint combined area AS IS pBmpOld = dcmm.SelectObject( &m_bmpScreenDst ); int cx = _rcClient.Width(); int cy = _rcClient.Height(); int _cx = cx; int _cy = (cy * m_nAnimPercent) / 100; visible_items_t v; _GetVisibleItems( dcmm.GetSafeHdc(), // dc.GetSafeHdc() v ); if( v.GetSize() == 0 ) { // if menu is empty int nOldStretchBltMode = pPaintDC->SetStretchBltMode( g_PaintManager.m_bIsWinNT ? HALFTONE : COLORONCOLOR ); pPaintDC->StretchBlt( _rcClient.left, _rcClient.top, _cx, _cy, &dcmm, _rcClient.left, _rcClient.top, cx, cy, SRCCOPY ); pPaintDC->SetStretchBltMode( nOldStretchBltMode ); } // if menu is empty else { // if menu is NOT empty int y_pos_src = _rcClient.top; int y_pos_dst = _rcClient.top; INT vis_iter = 0; int nItemIndex = 0; int nItemCount = v.GetSize(); ASSERT( nItemCount > 0 ); expand_effect_rects_container_t vRects; for( ; vis_iter < v.GetSize(); ++vis_iter, ++nItemIndex ) { // calc rects for visible items VisibleItemDefinition_t & vi = v[vis_iter]; #ifdef _DEBUG ASSERT( vi.m_nIndex >= 0 && vi.m_nIndex < m_items_all.GetSize() ); // ASSERT( !vi.m_rcItem.IsRectEmpty() ); // ASSERT( dc.RectVisible(&vi.m_rcItem) ); MENUITEMDATA & mi = m_items_all[vi.m_nIndex]; ASSERT( mi.IsDisplayed() ); ASSERT( mi.GetCmdID() == vi.m_nHelperCmdID ); #endif // _DEBUG CRect rcItemSrc( vi.m_rcItem ); rcItemSrc.left = _rcClient.left; rcItemSrc.right = _rcClient.right; if( nItemIndex == 0 ) rcItemSrc.top = _rcClient.top; else if( nItemIndex == (nItemCount-1) ) rcItemSrc.bottom = _rcClient.bottom; int y_pos_src_next = y_pos_src + rcItemSrc.Height(); CRect rcItemDst( rcItemSrc ); rcItemDst.OffsetRect( 0, y_pos_dst - rcItemDst.top ); if( vi.m_bRarelyUsed ) rcItemDst.bottom = rcItemDst.top + (rcItemDst.Height() * m_nAnimPercent) / 100; int y_pos_dst_next = y_pos_dst + rcItemDst.Height(); ExpandEffectRects_t _eert( rcItemSrc, rcItemDst ); vRects.Add( _eert ); y_pos_dst = y_pos_dst_next; y_pos_src = y_pos_src_next; } // calc rects for visible items // y_pos_dst is now equal to size of // all compressed itsms ASSERT( y_pos_dst <= y_pos_src ); if( m_bCombineWithEA && m_eCombineAlign == __CMBA_BOTTOM && y_pos_dst != y_pos_src ) { // expand from bottom to top INT iter_rects = 0; int nDstOffset = y_pos_src - y_pos_dst; for( ; iter_rects < vRects.GetSize(); ++iter_rects ) { // adjust destination rects ExpandEffectRects_t & eerc = vRects[ iter_rects ]; eerc.m_rcDst.OffsetRect( 0, nDstOffset ); } // adjust destination rects } // expand from bottom to top INT iter_rects = 0; for( ; iter_rects < vRects.GetSize(); ++iter_rects ) { // paint visible items ExpandEffectRects_t & eerc = vRects[ iter_rects ]; if( eerc.m_rcDst.IsRectEmpty() ) continue; if( g_bUseStretchOnExpandAnimation ) { int nOldStretchBltMode = pPaintDC->SetStretchBltMode( g_PaintManager.m_bIsWinNT ? HALFTONE : COLORONCOLOR ); // something better then Office XP pPaintDC->StretchBlt( eerc.m_rcDst.left, eerc.m_rcDst.top, eerc.m_rcDst.Width(), eerc.m_rcDst.Height(), &dcmm, eerc.m_rcSrc.left, eerc.m_rcSrc.top, eerc.m_rcSrc.Width(), eerc.m_rcSrc.Height(), SRCCOPY ); pPaintDC->SetStretchBltMode( nOldStretchBltMode ); } // if( g_bUseStretchOnExpandAnimation ) else // somthing really like Office XP pPaintDC->BitBlt( eerc.m_rcDst.left, eerc.m_rcDst.top, eerc.m_rcDst.Width(), eerc.m_rcDst.Height(), &dcmm, eerc.m_rcSrc.left, eerc.m_rcSrc.top, SRCCOPY ); } // paint visible items } // if menu is NOT empty } break; // case __AT_CONTENT_EXPAND case __AT_CONTENT_DISPLAY: if( tmp!= NULL && src!=NULL && dst != NULL ) { pBmpOld = dcmm.SelectObject( &m_bmpScreenDst ); pPaintDC->BitBlt( rcClient.left, rcClient.top, cx, cy, &dcmm, 0, 0, SRCCOPY ); } break; // case __AT_CONTENT_DISPLAY case __AT_FADE: if( tmp!= NULL && src!=NULL && dst != NULL ) { ASSERT( m_nAnimPercent >= 0 && m_nAnimPercent <= 100 && m_nAnimPercentOld >= 0 && m_nAnimPercentOld <= 100 && m_nAnimPercentOld <= m_nAnimPercent ); pBmpOld = dcmm.SelectObject( &m_bmpScreenTmp ); for( int pixel = 0; pixel < cx * cy; pixel++ ) { COLORREF c0 = *dst++; COLORREF c1 = *src++; *tmp++ = RGB( (m_nAnimPercent*long(GetRValue(c0)) + (100L-m_nAnimPercent)*long(GetRValue(c1)) ) / 100L, (m_nAnimPercent*long(GetGValue(c0)) + (100L-m_nAnimPercent)*long(GetGValue(c1)) ) / 100L, (m_nAnimPercent*long(GetBValue(c0)) + (100L-m_nAnimPercent)*long(GetBValue(c1)) ) / 100L ); } // for( int pixel = 0; pixel < cx * cy; pixel++ ) pPaintDC->BitBlt( rcClient.left, rcClient.top, cx, cy, &dcmm, 0, 0, SRCCOPY ); } break; // case __AT_FADE #ifdef _DEBUG default: ASSERT( FALSE ); break; // default #endif // _DEBUG } // switch( m_AnimationType ) } // if( !bFail ) if( pBmpOld != NULL ) dcmm.SelectObject( pBmpOld ); if( pOldPalette != NULL ) pPaintDC->SelectPalette( pOldPalette, FALSE ); } void CExtPopupBaseWnd::_DoPaint( CDC & dcPaint, bool bUseBackBuffer /*= true*/ ) { ASSERT_VALID( this ); dcPaint; bUseBackBuffer; } void CExtPopupBaseWnd::OnTimer(UINT nIDEvent) { ASSERT_VALID( this ); switch( nIDEvent ) { case ID_TIMER_DELAY_SHOW: { VERIFY( KillTimer(ID_TIMER_DELAY_SHOW) ); ShowWindow( SW_SHOWNA ); Invalidate( FALSE ); UpdateWindow(); return; } // case ID_TIMER_DELAY_SHOW case ID_TIMER_ANIMATION: if( !m_bAnimFinished ) { clock_t nCurrAnimTime = clock(); int nDuration = nCurrAnimTime - g_nLastAnimTime; int nSteps = (int) (0.5 + (float) nDuration / ID_PERIOD_ANIMATION); switch( m_AnimationType ) { case __AT_CONTENT_DISPLAY: m_bAnimFinished = true; break; case __AT_FADE: case __AT_CONTENT_EXPAND: case __AT_ROLL: case __AT_SLIDE: case __AT_ROLL_AND_STRETCH: case __AT_SLIDE_AND_STRETCH: case __AT_NOISE: case __AT_BOXES: case __AT_CIRCLES: case __AT_HOLES: m_nAnimPercentOld = m_nAnimPercent; m_nAnimPercent += g_nAnimStepMetric; if( m_nAnimPercent > 100 + nSteps * g_nAnimStepMetric ) m_nAnimPercent = 101; if( m_nAnimPercent > 100 ) m_bAnimFinished = true; break; #ifdef _DEBUG default: ASSERT( FALSE ); break; #endif // _DEBUG } // switch( m_AnimationType ) if( m_bAnimFinished ) { if( !_FindCustomizeMode() ) { g_SoundPlayer->PlaySound( m_ePlaySoundOnAnimationFinished ); m_ePlaySoundOnAnimationFinished = CExtSoundPlayer::__NO_SOUND; } // if( !_FindCustomizeMode() ) KillTimer(ID_TIMER_ANIMATION); m_AnimationType = g_DefAnimationType; } // if( m_bAnimFinished ) if( GetSafeHwnd() != NULL ) { if( m_bAnimFinished ) _EndAnimation(); else Invalidate( FALSE ); g_nLastAnimTime = nCurrAnimTime; } } // if( !m_bAnimFinished ) if( m_bAnimFinished ) if( IsKindOf(RUNTIME_CLASS(CExtPopupMenuWnd)) ) ((CExtPopupMenuWnd *)this)-> GetSite().SetAnimated( NULL ); return; // case ID_TIMER_ANIMATION default: __BaseClassOfCExtPopupBaseWnd::OnTimer(nIDEvent); break; // default } // switch( nIDEvent ) } int CExtPopupBaseWnd::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message) { ASSERT_VALID( this ); pDesktopWnd; nHitTest; message; if( _FindCustomizeMode() ) { if( IsKindOf(RUNTIME_CLASS(CExtPopupMenuWnd)) ) { /// ((CExtPopupMenuWnd*)this)->_ItemFocusCancel( FALSE ); ((CExtPopupMenuWnd*)this)->_DoResetChainPositions(); } // if( IsKindOf(RUNTIME_CLASS(CExtPopupMenuWnd)) ) else SetWindowPos( &CWnd::wndTopMost, -1, -1, -1, -1, SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE ); return MA_NOACTIVATE; } HWND hWndInPlace = ::GetWindow( m_hWnd, GW_CHILD ); if( hWndInPlace != NULL ) { CPoint ptScreenClick; if( ! ::GetCursorPos(&ptScreenClick) ) return MA_NOACTIVATEANDEAT; HWND hWndFromPoint = ::WindowFromPoint( ptScreenClick ); if( hWndFromPoint != NULL && (::GetWindowLong(hWndFromPoint,GWL_STYLE)&WS_CHILD) != 0 && ::GetParent(hWndFromPoint) == m_hWnd ) return MA_ACTIVATE; } // if( hWndInPlace != NULL ) return MA_NOACTIVATEANDEAT; //return CExtPopupBaseWnd::OnMouseActivate(pDesktopWnd, nHitTest, message); } void CExtPopupMenuWnd::_DoShowChain( int nCmdShow // = SW_SHOWNA ) { ASSERT_VALID( this ); if( m_hWnd == NULL || (! ::IsWindow(m_hWnd) ) ) return; ShowWindow( nCmdShow ); if( m_nCurIndex < 0 ) return; MENUITEMDATA & mi = _GetItemRef( m_nCurIndex ); if( !mi.IsPopup() ) return; mi.GetPopup()->_DoShowChain( nCmdShow ); } void CExtPopupMenuWnd::_DoResetChainPositions() { ASSERT_VALID( this ); CExtPopupMenuWnd * pChild = NULL; if( m_nCurIndex >= 0 ) { MENUITEMDATA & mi = _GetItemRef( m_nCurIndex ); if( mi.IsPopup() ) { pChild = mi.GetPopup(); if( pChild->GetSafeHwnd() == NULL || (! pChild->IsWindowVisible() ) ) pChild = NULL; } // if( mi.IsPopup() ) } // if( m_nCurIndex >= 0 ) if( pChild != NULL ) pChild->_DoResetChainPositions(); _DoResetChainPositionsImpl( NULL ); } void CExtPopupMenuWnd::_DoResetChainPositionsImpl( CExtPopupMenuWnd * pPrev ) { SetWindowPos( ( pPrev == NULL ) ? (&CWnd::wndTopMost) : pPrev, 0, 0, 0, 0, SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE |SWP_NOREDRAW ); { // BLOCK : DC painting CClientDC dc( this ); _DoPaint( dc ); } // BLOCK : DC painting if( m_pWndParentMenu != NULL ) m_pWndParentMenu->_DoResetChainPositionsImpl( this ); } BOOL CExtPopupBaseWnd::OnEraseBkgnd(CDC* pDC) { ASSERT_VALID( this ); pDC; return TRUE; } void CExtPopupBaseWnd::OnNcPaint() { ASSERT_VALID( this ); } void CExtPopupBaseWnd::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp) { ASSERT_VALID( this ); bCalcValidRects; lpncsp; /// __BaseClassOfCExtPopupBaseWnd::OnNcCalcSize(bCalcValidRects, lpncsp); } void CExtPopupBaseWnd::OnSize(UINT nType, int cx, int cy) { ASSERT_VALID( this ); __BaseClassOfCExtPopupBaseWnd::OnSize(nType, cx, cy); Invalidate(FALSE); } BOOL CExtPopupBaseWnd::DestroyWindow() { ASSERT_VALID( this ); if( !(::IsWindow(GetSafeHwnd())) ) return TRUE; return __BaseClassOfCExtPopupBaseWnd::DestroyWindow(); } void CExtPopupBaseWnd::PostNcDestroy() { ASSERT_VALID( this ); } void CExtPopupMenuWnd::PostNcDestroy() { ASSERT_VALID( this ); if( _FindCustomizeMode() ) return; if( m_bTopLevel ) { ASSERT( m_hWndCmdReciever != NULL ); if( ::IsWindow(m_hWndCmdReciever) ) ::SendMessage( m_hWndCmdReciever, g_nMsgNotifyMenuClosed, 0, LPARAM( this ) ); CExtPopupMenuSite & _site = GetSite(); ASSERT( !_site.IsEmpty() ); if( //!_site.IsEmpty() && !_site.IsShutdownMode() ) { _site.DoneInstance(); ASSERT( _site.IsEmpty() ); ASSERT( !_site.IsShutdownMode() ); } } // if( m_bTopLevel ) } bool CExtPopupBaseWnd::_FindHelpMode() const { // if( ::AfxGetApp()->m_bHelpMode ) // return true; return false; } bool CExtPopupMenuWnd::_FindHelpMode() const { if( (m_dwTrackFlags&TPMX_HELP_CTX_MODE) != 0 ) return true; if( m_pWndParentMenu != NULL ) return m_pWndParentMenu->_FindHelpMode(); return CExtPopupBaseWnd::_FindHelpMode(); } #if (!defined __EXT_MFC_NO_CUSTOMIZE) CExtCustomizeSite * CExtPopupMenuWnd::_FindCustomizeSite() const { if( m_pCustomizeSite != NULL ) return (CExtCustomizeSite *)m_pCustomizeSite; if( m_pWndParentMenu != NULL ) return m_pWndParentMenu->_FindCustomizeSite(); return NULL; } #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) bool CExtPopupBaseWnd::_FindCustomizeMode() const { return false; } bool CExtPopupMenuWnd::_FindCustomizeMode() const { if( (m_dwTrackFlags&TPMX_CUSTOMIZE_MODE) != 0 ) return true; if( m_pWndParentMenu != NULL ) return m_pWndParentMenu->_FindCustomizeMode(); return false; } BOOL CExtPopupBaseWnd::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { ASSERT_VALID( this ); if( _FindHelpMode() ) { SetCursor( afxData.hcurHelp ); return TRUE; } return __BaseClassOfCExtPopupBaseWnd::OnSetCursor(pWnd, nHitTest, message); } ///////////////////////////////////////////////////////////////////////////// // CExtPopupMenuTipWnd IMPLEMENT_DYNCREATE(CExtPopupMenuTipWnd, CExtPopupBaseWnd) CExtPopupMenuTipWnd::CExtPopupMenuTipWnd() { m_hIcon = NULL; m_IconSize.cx = m_IconSize.cy = 0; m_sText = _T(""); m_bFlipHorz = false; m_bFlipVert = false; m_hIcon = ::LoadIcon( NULL, IDI_INFORMATION ); m_IconSize.cx = m_IconSize.cy = 16; m_bAnimFinished = true; m_AnimationType = __AT_NONE; } CExtPopupMenuTipWnd::~CExtPopupMenuTipWnd() { if( m_hIcon != NULL ) { ::DestroyIcon( m_hIcon ); m_hIcon = NULL; } } BEGIN_MESSAGE_MAP(CExtPopupMenuTipWnd, CExtPopupBaseWnd) //{{AFX_MSG_MAP(CExtPopupMenuTipWnd) //}}AFX_MSG_MAP END_MESSAGE_MAP() #define CX_ROUNDED 12 // Tip horizontal roundness #define CY_ROUNDED 10 // Tip vertical roundness #define CX_LEADER 25 // Width of tip lead #define CY_LEADER 25 // Height of tip lead #define CX_ICON_MARGIN 5 // Width of margin between icon and tip text #define __TIP_OVER_METRIC 12 bool CExtPopupMenuTipWnd::GetWindowRegion( CDC* pDC, HRGN* hRegion, CSize *Size /* = NULL */ ) { ASSERT_VALID( this ); CRect rcWnd(0,0,0,0); POINT ptLeader[3]; CRgn LeaderRegion; CRgn CaptionRegion; CFont *pSysFont; ASSERT( pDC != NULL ); ASSERT( hRegion != NULL ); // Calculate the are for the tip text pSysFont = (CFont *)pDC->SelectObject( &(g_PaintManager->m_FontNormal) ); pDC->DrawText( m_sText, m_sText.GetLength(), &rcWnd, DT_CALCRECT ); pDC->SelectObject( pSysFont ); // Adjust for the rounded corners rcWnd.InflateRect(CX_ROUNDED, CY_ROUNDED); // Adjust for icon if( m_hIcon != NULL ) rcWnd.right = rcWnd.right + m_IconSize.cx + CX_ICON_MARGIN; if( rcWnd.Height() < m_IconSize.cy ) rcWnd.bottom = rcWnd.top + m_IconSize.cy; // Calculate the leader triangle coordinates ptLeader[0].x = rcWnd.Width() - CX_ROUNDED; ptLeader[0].y = rcWnd.Height() - CY_ROUNDED; ptLeader[1].x = ptLeader[0].x; ptLeader[1].y = ptLeader[0].y + CY_LEADER; ptLeader[2].x = ptLeader[0].x - CX_LEADER; ptLeader[2].y = rcWnd.Height() - CY_ROUNDED; CRect rcRoundRectRgn(CPoint(0,0),rcWnd.Size()); CRect rcRectRgn( 0, 0, rcWnd.Width(), rcWnd.Height() + CY_LEADER ); m_bFlipHorz = false; m_bFlipVert = false; CWnd * pWndSearchMon = GetParent(); ASSERT_VALID( pWndSearchMon ); ASSERT( pWndSearchMon->GetSafeHwnd() != NULL ); ASSERT( ::IsWindow( pWndSearchMon->GetSafeHwnd() ) ); CExtPaintManager::monitor_parms_t _mp; CExtPaintManager::stat_GetMonitorParms( _mp, pWndSearchMon ); CRect rcDesktop = g_bUseDesktopWorkArea ? _mp.m_rcWorkArea : _mp.m_rcMonitor ; if( m_ptTrack.x - rcWnd.Width() < rcDesktop.left ) { m_bFlipHorz = true; ptLeader[0].x = CX_ROUNDED; ptLeader[0].y = rcWnd.Height() - CY_ROUNDED; ptLeader[1].x = ptLeader[0].x; ptLeader[1].y = ptLeader[0].y + CY_LEADER; ptLeader[2].x = ptLeader[0].x + CX_LEADER; ptLeader[2].y = ptLeader[0].y; } if( m_ptTrack.y - rcWnd.Height() - CY_ROUNDED*2 < rcDesktop.top ) { m_bFlipVert = true; ptLeader[0].y -= rcWnd.Height() - CY_ROUNDED*2; ptLeader[1].y = ptLeader[0].y - CY_LEADER; ptLeader[2].y -= ptLeader[0].y; } // Create the caption region CaptionRegion.CreateRoundRectRgn( rcRoundRectRgn.left,rcRoundRectRgn.top,rcRoundRectRgn.right,rcRoundRectRgn.bottom, CX_ROUNDED, CY_ROUNDED ); // Create the leader region LeaderRegion.CreatePolygonRgn(ptLeader, 3, ALTERNATE); // Create window region *hRegion = ::CreateRectRgn( rcRectRgn.left,rcRectRgn.top,rcRectRgn.right,rcRectRgn.bottom ); // Combine the regions CombineRgn(*hRegion, CaptionRegion.operator HRGN(), LeaderRegion.operator HRGN(), RGN_OR); if( m_bFlipVert ) OffsetRgn(*hRegion,0,CY_LEADER); // Set the window size if (Size != NULL) { Size->cx = rcWnd.Width(); Size->cy = rcWnd.Height() + CY_LEADER; } return true; } void CExtPopupMenuTipWnd::_DoPaint( CDC & dcPaint, bool bUseBackBuffer /*= true*/ ) { ASSERT_VALID( this ); bUseBackBuffer; CDC & dc = dcPaint; CRect rc; CBrush WindowBrush; CBrush FrameBrush; CBrush InnerFrameBrush; HRGN hRegion; CRgn *pRegion; CFont *pSysFont; // Get the client rectangle GetClientRect(rc); // Create the brushes InnerFrameBrush.CreateSolidBrush( g_PaintManager->GetColor(COLOR_3DFACE) ); FrameBrush.CreateSolidBrush( g_PaintManager->GetColor(COLOR_3DDKSHADOW) ); WindowBrush.CreateSolidBrush( g_PaintManager->GetColor(COLOR_INFOBK) ); // Get the window region hRegion = CreateRectRgnIndirect(&rc); GetWindowRgn(hRegion); pRegion = CRgn::FromHandle(hRegion); // Draw the frame dc.FillRgn(pRegion, &WindowBrush); dc.FrameRgn(pRegion, &InnerFrameBrush, 3, 3); dc.FrameRgn(pRegion, &FrameBrush, 1, 1); // Adjust the area for the icon rc.DeflateRect(CX_ROUNDED, CY_ROUNDED, 0, 0); if( m_hIcon != NULL ) rc.left += m_IconSize.cx + CX_ICON_MARGIN; // Set the font pSysFont = (CFont *)dc.SelectObject( &(g_PaintManager->m_FontNormal) ); // Draw the tip text dc.SetBkMode( TRANSPARENT ); int nIconVertPos = CY_ROUNDED; if( m_bFlipVert ) { rc.OffsetRect(0,CY_LEADER); nIconVertPos += CY_LEADER; } COLORREF clrOltTextColor = dc.SetTextColor( g_PaintManager->GetColor(COLOR_INFOTEXT) ); dc.DrawText( m_sText, m_sText.GetLength(), &rc, DT_TOP | DT_LEFT ); dc.SetTextColor( clrOltTextColor ); // Draw the icon if( m_hIcon != NULL ) DrawIconEx( dc.GetSafeHdc(), CX_ROUNDED, nIconVertPos, m_hIcon, m_IconSize.cx, m_IconSize.cy, 0, NULL, DI_NORMAL ); // Clean up GDI ::DeleteObject(hRegion); //if( pSysFont != NULL ) dc.SelectObject(pSysFont); } void CExtPopupMenuTipWnd::SetText(__EXT_MFC_SAFE_LPCTSTR lpszText) { ASSERT_VALID( this ); m_sText = (lpszText==NULL) ? _T("") : lpszText; m_sText.TrimLeft(); m_sText.TrimRight(); } void CExtPopupMenuTipWnd::SetIcon(HICON hIcon) { ASSERT_VALID( this ); if( m_hIcon != NULL ) { ::DestroyIcon( m_hIcon ); m_hIcon = NULL; } if( hIcon == NULL ) { m_IconSize = CSize( 0, 0 ); return; } ICONINFO IconInfo; m_hIcon = hIcon; // Get the icon sizes ZeroMemory( &IconInfo, sizeof(ICONINFO) ); ::GetIconInfo( m_hIcon, &IconInfo ); ASSERT( IconInfo.hbmColor != NULL || IconInfo.hbmMask != NULL ); m_IconSize.cx = (BYTE)(IconInfo.xHotspot * 2); m_IconSize.cy = (BYTE)(IconInfo.yHotspot * 2); if( m_IconSize.cx == 0 || m_IconSize.cy == 0 ) { ASSERT( IconInfo.hbmColor != NULL || IconInfo.hbmMask != NULL ); BITMAP bi; ::memset( &bi, 0, sizeof(BITMAP) ); ::GetObject( (IconInfo.hbmColor != NULL) ? IconInfo.hbmColor : IconInfo.hbmMask, sizeof(BITMAP), &bi ); ASSERT( bi.bmWidth > 0 && bi.bmHeight > 0 ); m_IconSize.cx = bi.bmWidth; m_IconSize.cy = bi.bmHeight; } // if( m_IconSize.cx == 0 || m_IconSize.cy == 0 ) ASSERT( m_IconSize.cx > 0 && m_IconSize.cy > 0 ); ::DeleteObject( IconInfo.hbmMask ); ::DeleteObject( IconInfo.hbmColor ); if( ::IsWindow(m_hWnd) ) RedrawWindow(); } bool CExtPopupMenuTipWnd::Show( CWnd * pWndParent, const RECT & rcExcludeArea // = CExtPopupMenuTipWnd::rcNoExcludeArea ) { ASSERT_VALID( this ); ASSERT_VALID( pWndParent ); ASSERT( pWndParent->GetSafeHwnd() != NULL ); HCURSOR hCursor = ::LoadCursor(NULL, IDC_ARROW); ASSERT( hCursor != NULL ); if( GetSafeHwnd() == NULL ) { CExtSafeString strClassName = ::AfxRegisterWndClass ( __POPUP_WNDCLASS_STYLES__, hCursor, (HBRUSH)(COLOR_BTNFACE + 1), NULL ); BOOL bCreateResult = CWnd::CreateEx( WS_EX_TOPMOST, strClassName, NULL, WS_POPUP, 0, 0, 0, 0, pWndParent->GetSafeHwnd(), NULL, NULL ); ASSERT( bCreateResult ); if( !bCreateResult ) return false; } // if( GetSafeHwnd() == NULL ) #ifdef _DEBUG else { ASSERT_VALID( pWndParent ); ASSERT( ::IsWindow( pWndParent->GetSafeHwnd() ) ); // CWnd * pExistingParent = GetParent(); // ASSERT( pWndParent == pExistingParent ); } // else from if( GetSafeHwnd() == NULL ) #endif // _DEBUG ASSERT_VALID( this ); m_rcExcludeArea = rcExcludeArea; m_rcExcludeArea.NormalizeRect(); CPoint ptTipTarget( m_rcExcludeArea.TopLeft() ); ptTipTarget += CSize( __TIP_OVER_METRIC/2, __TIP_OVER_METRIC/2 ); m_ptTrack = ptTipTarget; CDC * pDC = GetDC(); ASSERT_VALID( pDC ); HRGN hRegion; CSize WindowSize; VERIFY( GetWindowRegion(pDC, &hRegion, &WindowSize) ); ReleaseDC(pDC); VERIFY( ::SetWindowRgn( m_hWnd, hRegion, TRUE ) ); if( m_bFlipHorz ) m_ptTrack.x += m_rcExcludeArea.Width() - __TIP_OVER_METRIC + WindowSize.cx - CX_ROUNDED*2 ; if( m_bFlipVert ) m_ptTrack.y += m_rcExcludeArea.Height() - __TIP_OVER_METRIC + WindowSize.cy - CX_ROUNDED*2 ; CPoint ptWndPos( m_ptTrack.x - WindowSize.cx + CX_ROUNDED, m_ptTrack.y - WindowSize.cy + CY_ROUNDED ); SetWindowPos( &CWnd::wndTopMost, ptWndPos.x, ptWndPos.y, WindowSize.cx, WindowSize.cy, SWP_NOACTIVATE //| SWP_SHOWWINDOW ); CRect rcWnd(ptWndPos,WindowSize); MoveWindow(&rcWnd); // ASSERT( IsWindowVisible() ); ::SetCursor(hCursor); // Invalidate( FALSE ); // UpdateWindow(); SetTimer( ID_TIMER_DELAY_SHOW, ID_PERIOD_DELAY_SHOW, NULL ); return true; } void CExtPopupMenuTipWnd::Hide() { ASSERT_VALID( this ); if( GetSafeHwnd() != NULL ) { KillTimer( ID_TIMER_DELAY_SHOW ); ShowWindow( SW_HIDE ); } m_rcExcludeArea.SetRectEmpty(); } ///////////////////////////////////////////////////////////////////////////// // CExtPopupMenuWnd // is allowed menu item positioning without // using only & - marked text bool CExtPopupMenuWnd::g_bAllowNonAccelPositioning = false; IMPLEMENT_DYNCREATE(CExtPopupMenuWnd, CExtPopupBaseWnd) CExtPopupMenuWnd::CExtPopupMenuWnd() : m_pWndParentMenu( NULL ) , m_hWndCmdReciever( m_hWndCmdReciever ) , m_nLeftAreaWidth( 0 ) #if (!defined __EXT_MFC_NO_CUSTOMIZE) , m_pNode( NULL ) , m_pDragSrcNode( NULL ) , m_nDragSrcIdx( -1 ) , m_bHelperNoRemoveSrc( false ) , m_bHelperDragOverPassed( false ) , m_pCustomizeSite( NULL ) , m_nHelperDropIndexBefore( -1 ) , m_bHelperNoHideChild( false ) , m_ptHelperDragStart( 0, 0 ) #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) { __VPC_INC; _Init(); } CExtPopupMenuWnd::~CExtPopupMenuWnd() { _OnCancelMode( true ); if( m_bTopLevel ) { VERIFY( _BuildItems( NULL, true ) ); } __VPC_DEC; #ifdef _DEBUG if( m_bTopLevel ) { __VPC_VERIFY_0; } #endif // _DEBUG } bool CExtPopupMenuWnd::TestHoverEnabledFromActiveHWND( HWND hWndTestFrom, HWND hWndActive, // = ::GetActiveWindow(), bool bCheckEnabled, // = true, bool bCheckVisible, // = true, bool bCheckExtPopupMenuTracking // = true ) { if( bCheckExtPopupMenuTracking ) { if( CExtPopupMenuWnd::IsMenuTracking() ) return false; } // if( bCheckExtPopupMenuTracking ) if( hWndTestFrom == NULL || ( ! ::IsWindow( hWndTestFrom ) ) ) return false; if( hWndActive == NULL || ( ! ::IsWindow( hWndActive ) ) ) return false; if( bCheckEnabled ) { if( ! ::IsWindowEnabled( hWndTestFrom ) ) return false; if( ! ::IsWindowEnabled( hWndActive ) ) return false; } // if( bCheckEnabled ) DWORD dwWndStyle; if( bCheckVisible ) { dwWndStyle = (DWORD) ::GetWindowLong( hWndTestFrom, GWL_STYLE ); if( (dwWndStyle & WS_VISIBLE) == 0 ) return false; dwWndStyle = (DWORD) ::GetWindowLong( hWndActive, GWL_STYLE ); if( (dwWndStyle & WS_VISIBLE) == 0 ) return false; } // if( bCheckVisible ) const DWORD dwTestStyles = (WS_VISIBLE|WS_POPUP); for( HWND hWndParentOfTest = ::GetParent( hWndTestFrom ); hWndParentOfTest != NULL; hWndParentOfTest = ::GetParent( hWndParentOfTest ) ) { // walk parent popup windows of hWndTestFrom ASSERT( ::IsWindow( hWndParentOfTest ) ); dwWndStyle = (DWORD) ::GetWindowLong( hWndParentOfTest, GWL_STYLE ); if( (dwWndStyle&dwTestStyles) == 0L ) continue; if( hWndParentOfTest == hWndActive ) return true; for( HWND hWndParentOfActive = hWndActive; hWndParentOfActive != NULL; hWndParentOfActive = ::GetParent( hWndParentOfActive ) ) { // walk parent popup windows of hWndActive ASSERT( ::IsWindow( hWndParentOfActive ) ); dwWndStyle = (DWORD) ::GetWindowLong( hWndParentOfActive, GWL_STYLE ); if( (dwWndStyle&dwTestStyles) == 0L ) continue; if( hWndParentOfActive == hWndParentOfTest ) return true; } // walk parent popup windows of hWndActive } // walk parent popup windows of hWndTestFrom return false; } void CExtPopupMenuWnd::_Init() { ASSERT_VALID( this ); _InitAnimation(); m_nDyScrollOffset = 0; m_bTopLevel = m_bScrollingAvailable = m_bExpandAvailable = m_bExpandWasPressed = m_bCombineWithEA = false; m_dwTrackFlags = 0; m_nWaitingExpandTickCount = 0; m_nCurIndex = m_nDelayedFocusItemIndex = IDX_NOTHING; m_nScrollingDirection = 0; m_rcScrollTop.SetRectEmpty(); m_rcScrollBottom.SetRectEmpty(); m_rcExpandBtn.SetRectEmpty(); m_eCombineAlign = __CMBA_NONE; m_pCbPaintCombinedCookie = NULL; m_pCbPaintCombinedContent = NULL; m_bCookieIsObject = false; } CObject * CExtPopupBaseWnd::GetCoockieAsObject() { if( (!m_bCookieIsObject) || m_pCbPaintCombinedCookie == NULL ) return NULL; CObject * pObj = (CObject*)m_pCbPaintCombinedCookie; ASSERT_VALID( pObj ); return pObj; } bool CExtPopupBaseWnd::IsToolBtnCombinedArea() const { if( !IsKindOf( RUNTIME_CLASS(CExtPopupMenuWnd) ) ) return false; CExtPopupMenuWnd * pPopup = (CExtPopupMenuWnd*)(this); // pPopup = pPopup->GetParentMenuWnd(); // if( pPopup == NULL ) // return false; if( (LPVOID)(CExtPopupMenuWnd::stat_paint_combined_menu_toolbtn) != (LPVOID)(pPopup->GetCbPaintCombinedContent()) ) return false; return true; } int CExtPopupMenuWnd::_GetCurIndex() const { ASSERT_VALID( this ); return m_nCurIndex; } int CExtPopupMenuWnd::_GetSpecBtnHeight() { int nHeight = g_PaintManager->GetMenuExpandButtonHeight(); ASSERT( nHeight > 0 ); return nHeight; } void CExtPopupMenuWnd::_RecalcLayoutImpl() { ASSERT_VALID( this ); CRect rcClient; _GetClientRect( &rcClient ); int nScrollBtnDy = _GetSpecBtnHeight(); int nMenuBorderSize = g_PaintManager->GetMenuBorderSize(); int nMenuShadowSize = 0; // _GetPopupShadowSize(); int nScrollBottomOffsetDy = 0; if( m_bExpandAvailable ) { m_rcExpandBtn.left = rcClient.left + nMenuBorderSize; m_rcExpandBtn.right = rcClient.right - (nMenuBorderSize + nMenuShadowSize); m_rcExpandBtn.bottom = rcClient.bottom - (nMenuBorderSize + nMenuShadowSize); m_rcExpandBtn.top = m_rcExpandBtn.bottom - nScrollBtnDy; nScrollBottomOffsetDy = - m_rcExpandBtn.Height(); m_rcExpandBtn.DeflateRect( __MI_HORZ_GAP_TO_BORDER, 0 ); m_rcExpandBtn.left += m_nLeftAreaWidth; } // if( m_bExpandAvailable ) if( m_bScrollingAvailable ) { m_rcScrollTop.left = m_rcScrollBottom.left = rcClient.left + nMenuBorderSize; m_rcScrollTop.right = m_rcScrollBottom.right = rcClient.right - (nMenuBorderSize + nMenuShadowSize); m_rcScrollTop.top = rcClient.top + nMenuBorderSize; m_rcScrollTop.bottom = m_rcScrollTop.top + nScrollBtnDy; m_rcScrollBottom.bottom = rcClient.bottom - (nMenuBorderSize + nMenuShadowSize); m_rcScrollBottom.top = m_rcScrollBottom.bottom - nScrollBtnDy; m_rcScrollBottom.OffsetRect(0,nScrollBottomOffsetDy); m_rcScrollTop.DeflateRect( __MI_HORZ_GAP_TO_BORDER, 0 ); m_rcScrollBottom.DeflateRect( __MI_HORZ_GAP_TO_BORDER, 0 ); m_rcScrollTop.left += m_nLeftAreaWidth; m_rcScrollBottom.left += m_nLeftAreaWidth; } // if( m_bScrollingAvailable ) } class CExtPopupMenuWnd::CExtPopupMenuCmdUI : public CCmdUI { public: // re-implementations only HWND m_hWndCmdReciever; CExtPopupMenuWnd * m_pPopup; CExtPopupMenuWnd::MENUITEMDATA * m_pItemDataActive; CExtPopupMenuCmdUI( HWND hWndCmdReciever, CExtPopupMenuWnd * pPopup ) : m_hWndCmdReciever( hWndCmdReciever ) , m_pPopup( pPopup ) , m_pItemDataActive( NULL ) { ASSERT( m_hWndCmdReciever != NULL && ::IsWindow(m_hWndCmdReciever) ); ASSERT_VALID( m_pPopup ); CCmdUI::m_pOther = NULL; // menu CCmdUI::m_nIndexMax = (UINT)m_pPopup->ItemGetCount(); CCmdUI::m_nIndex = 0; } void SetActiveIndex( int nIndex ) { ASSERT( m_hWndCmdReciever != NULL && ::IsWindow(m_hWndCmdReciever) ); ASSERT_VALID( m_pPopup ); CCmdUI::m_nIndex = (UINT)nIndex; ASSERT( CCmdUI::m_nIndex >= 0 && CCmdUI::m_nIndex < CCmdUI::m_nIndexMax ); m_pItemDataActive = &m_pPopup->_GetItemRef(nIndex); ASSERT( m_pItemDataActive != NULL ); CCmdUI::m_nID = m_pItemDataActive->GetCmdID(); if( m_pItemDataActive->IsPopup() || m_pItemDataActive->IsSeparator() || CExtCmdManager::IsSystemCommand( CCmdUI::m_nID ) ) return; CExtCmdItem * pCmdItem = g_CmdManager->CmdGetPtr( g_CmdManager->ProfileNameFromWnd(m_hWndCmdReciever), CCmdUI::m_nID ); if( pCmdItem == NULL ) return; // m_pItemDataActive->SetText( pCmdItem->m_sMenuText ); m_pItemDataActive->SetAccelText( pCmdItem->m_sAccelText ); m_pItemDataActive->AccelCharInit(); m_pItemDataActive->MeasureItem(); } virtual void Enable(BOOL bOn) { CCmdUI::m_bEnableChanged = TRUE; ASSERT( m_hWndCmdReciever != NULL && ::IsWindow(m_hWndCmdReciever) ); ASSERT_VALID( m_pPopup ); ASSERT( m_pItemDataActive != NULL ); /* if( m_pItemDataActive->IsPopup() ) { #if (!defined __EXT_MFC_NO_CUSTOMIZE) CExtCustomizeSite * pSite = CExtCustomizeSite::GetCustomizeSite(m_hWndCmdReciever); if( !( m_pItemDataActive->IsInplaceEdit() && pSite != NULL && m_pItemDataActive->GetCmdNode() != NULL ) ) #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) return; } */ if( m_pItemDataActive->IsPopup() && m_pItemDataActive->GetCmd() == NULL ) return; if( m_pItemDataActive->IsForceEnabled() ) bOn = TRUE; m_pItemDataActive->Enable( bOn ? true : false ); // m_pItemDataActive->MeasureItem(); } virtual void SetRadio(BOOL bOn) { ASSERT( m_hWndCmdReciever != NULL && ::IsWindow(m_hWndCmdReciever) ); ASSERT_VALID( m_pPopup ); ASSERT( m_pItemDataActive != NULL ); if( m_pItemDataActive->IsPopup() ) return; m_pItemDataActive->Radio( bOn ? true : false ); // m_pItemDataActive->MeasureItem(); } virtual void SetCheck(int nCheck) { ASSERT_VALID( m_pPopup ); ASSERT( m_pItemDataActive != NULL ); if( m_pItemDataActive->IsPopup() ) return; m_pItemDataActive->Check( nCheck ? true : false ); // m_pItemDataActive->MeasureItem(); } virtual void SetText( LPCTSTR lpszText ) { ASSERT( m_hWndCmdReciever != NULL && ::IsWindow(m_hWndCmdReciever) ); ASSERT_VALID( m_pPopup ); ASSERT( m_pItemDataActive != NULL ); if( lpszText == NULL ) return; if( m_pItemDataActive->IsPopup() ) return; m_pItemDataActive->SetText( lpszText ); m_pItemDataActive->MeasureItem(); } }; // class CExtPopupMenuWnd::CExtPopupMenuCmdUI void CExtPopupMenuWnd::_UpdateCmdUI() { ASSERT_VALID( this ); if( m_bTopLevel ) if( (m_dwTrackFlags&TPMX_NO_CMD_UI) != 0 ) return; ASSERT( m_hWndCmdReciever != NULL ); #if (!defined __EXT_MFC_NO_CUSTOMIZE) __EXT_MFC_SAFE_LPCTSTR strProfileName = g_CmdManager->ProfileNameFromWnd(m_hWndCmdReciever); CExtCustomizeSite * pSite = CExtCustomizeSite::GetCustomizeSite(m_hWndCmdReciever); #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) BOOL bDisableIfNoHndler = TRUE; CExtPopupMenuCmdUI _state( m_hWndCmdReciever, this ); bool bResyncItems = false; for( INT _iter = 0; _iter < m_items_all.GetSize(); _iter++ ) { // walk all items _state.SetActiveIndex( _iter ); ASSERT( _state.m_pItemDataActive != NULL ); if( _state.m_pItemDataActive->IsSeparator() ) continue; if( _state.m_pItemDataActive->IsPopup() ) { #if (!defined __EXT_MFC_NO_CUSTOMIZE) if( /* _state.m_pItemDataActive->IsInplaceEdit() &&*/ pSite != NULL && _state.m_pItemDataActive->GetCmdNode() != NULL ) { UINT _nCmdIdSaved = _state.m_pItemDataActive->m_nCmdID; _state.m_nID = _state.m_pItemDataActive -> GetCmdNode() -> GetCmdID( false ); ASSERT( CExtCmdManager::IsCommand( _state.m_nID ) ); HWND hWndCmdReciever = _state.m_pItemDataActive->GetCmdReciever(); ASSERT( hWndCmdReciever != NULL ); ASSERT( ::IsWindow(hWndCmdReciever) ); CWnd * pWndCmdReciever = CWnd::FromHandle( hWndCmdReciever ); ASSERT_VALID( pWndCmdReciever ); _state.DoUpdate( pWndCmdReciever, bDisableIfNoHndler ); #if (!defined __EXT_MFC_NO_CUSTOMIZE) if( pSite != NULL && pSite->IsCustomizeMode() ) _state.m_pItemDataActive->SetForceEnabled( true ); #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) _state.m_pItemDataActive->m_nCmdID = _nCmdIdSaved; _state.m_pItemDataActive->GetPopup()->_UpdateCmdUI(); continue; } else #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) { _state.m_pItemDataActive->GetPopup()->_UpdateCmdUI(); continue; } } if( _state.m_pItemDataActive->IsExtraMark() ) { bResyncItems = true; continue; } #if (!defined __EXT_MFC_NO_CUSTOMIZE) if( pSite != NULL && pSite->IsUserBarCommand( _state.m_pItemDataActive->GetCmdID() ) && strProfileName != NULL ) { _state.m_pItemDataActive->SetForceEnabled( true ); CExtCmdItem * pCmdItem = g_CmdManager->CmdGetPtr( strProfileName, _state.m_pItemDataActive->GetCmdID() ); ASSERT( pCmdItem != NULL ); CExtToolControlBar * pUserBar = pSite->GetUserBar( _state.m_pItemDataActive->GetCmdID() ); ASSERT_VALID( pUserBar ); bool bCheck = pUserBar->IsVisible() ? true : false; pCmdItem->StateSetCheck( bCheck ); _state.SetCheck( bCheck ); continue; } #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) if( CExtCmdManager::IsCommandNeedsSpecUpdate( _state.m_pItemDataActive->GetCmdID() ) || CExtCmdManager::IsSystemCommand( _state.m_pItemDataActive->GetCmdID() ) ) continue; HWND hWndCmdReciever = _state.m_pItemDataActive->GetCmdReciever(); ASSERT( hWndCmdReciever != NULL ); ASSERT( ::IsWindow(hWndCmdReciever) ); CWnd * pWndCmdReciever = CWnd::FromHandle( hWndCmdReciever ); ASSERT_VALID( pWndCmdReciever ); _state.DoUpdate( pWndCmdReciever, bDisableIfNoHndler ); #if (!defined __EXT_MFC_NO_CUSTOMIZE) if( pSite != NULL && pSite->IsCustomizeMode() ) _state.m_pItemDataActive->SetForceEnabled( true ); #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) } // walk all items if( bResyncItems ) _SyncItems(); } bool CExtPopupMenuWnd::MENUITEMDATA::ConstructPopup() { ASSERT( m_iconPopup.IsEmpty() ); ASSERT( m_pWndChild == NULL ); m_pWndChild = new CExtPopupMenuWnd; ASSERT( m_hWndSpecCmdReciever != NULL ); ASSERT( ::IsWindow(m_hWndSpecCmdReciever) ); m_pWndChild->m_hWndCmdReciever = m_hWndSpecCmdReciever; return true; } void CExtPopupMenuWnd::MENUITEMDATA::DestroyPopup() { VERIFY( SetPopupIcon(NULL) ); if( m_pWndChild == NULL ) return; if( m_pWndChild->GetSafeHwnd() != NULL && ::IsWindow( m_pWndChild->GetSafeHwnd() ) ) m_pWndChild->DestroyWindow(); // else // delete m_pWndChild; delete m_pWndChild; m_pWndChild = NULL; } bool CExtPopupMenuWnd::_BuildItems( CMenu * pBuildMenu, bool bTopLevel ) { ASSERT_VALID( this ); #ifdef _DEBUG if( pBuildMenu != NULL ) { ASSERT( m_hWndCmdReciever != NULL ); ASSERT( ::IsWindow(m_hWndCmdReciever) ); } #endif // _DEBUG INT iter = 0; for( ; iter < m_items_all.GetSize(); iter++) { MENUITEMDATA & mi = m_items_all[ iter ]; if( mi.IsPopup() ) { mi.GetPopup()->m_hWndCmdReciever = m_hWndCmdReciever; mi.GetPopup()->_OnCancelMode(); VERIFY( mi.GetPopup()->_BuildItems( NULL, false ) ); mi.DestroyPopup(); } } // for( ; iter < m_items_all.GetSize(); iter++) m_items_all.RemoveAll(); if( pBuildMenu == NULL ) return true; ASSERT( pBuildMenu->GetSafeHmenu() != NULL ); m_bTopLevel = bTopLevel; if( m_bTopLevel ) m_pWndParentMenu = NULL; // build items loop bool bPrevWasSeparator = false; int nMruUpdateIndex = -1, nInsertedIndex = 0; int nMenuItemCount = pBuildMenu->GetMenuItemCount(); ASSERT( nMenuItemCount > 0 ); m_items_all.RemoveAll(); for( int nItemIndex=0; nItemIndex<nMenuItemCount; nItemIndex++ ) { UINT nMenuItemID = pBuildMenu->GetMenuItemID( nItemIndex ); if( ID_FILE_MRU_FIRST <= nMenuItemID && nMenuItemID <= ID_FILE_MRU_LAST ) { if( nMruUpdateIndex < 0 ) nMruUpdateIndex = nInsertedIndex; continue; } MENUITEMDATA mi; mi.SetCmdReciever( m_hWndCmdReciever ); VERIFY( mi.UpdateFromMenu( m_hWndCmdReciever, pBuildMenu, nItemIndex ) ); bool bIsSeparator = mi.IsSeparator(); if( bPrevWasSeparator && bIsSeparator ) continue; bPrevWasSeparator = bIsSeparator; if( mi.IsPopup() ) { CMenu * pSubMenu = pBuildMenu->GetSubMenu(nItemIndex); ASSERT( pSubMenu != NULL ); ASSERT( pSubMenu->GetSafeHmenu() != NULL ); mi.GetPopup()->m_hWndCmdReciever = m_hWndCmdReciever; mi.GetPopup()->_BuildItems( pSubMenu, false ); mi.GetPopup()->m_pWndParentMenu = this; } _InsertItem( -1, mi ); nInsertedIndex++; } // for( int nItemIndex=0; nItemIndex<nMenuItemCount; nItemIndex++ ) ASSERT( m_items_all.GetSize() <= nMenuItemCount ); int nMruInsertCount = 0; if( nMruUpdateIndex >= 0 ) { // insert recently opened file items ASSERT( nMruUpdateIndex < nMenuItemCount ); CRecentFileList * pRecentFileList = InternalFriendlyWinApp::_GetFriendlyApp()-> _GetRecentFileList(); if( pRecentFileList != NULL ) { // can be null !? int nRecentCount = pRecentFileList->GetSize(); TCHAR sCurrDir[_MAX_PATH+1]; ::memset(sCurrDir,0,sizeof(sCurrDir)); ::GetCurrentDirectory(_MAX_PATH,sCurrDir); int nLenCurDir = _tcslen(sCurrDir); for( nItemIndex=0; nItemIndex<nRecentCount; nItemIndex++ ) { CExtSafeString sDisplayName( _T("") ); if( !pRecentFileList->GetDisplayName( *((CString *)&sDisplayName), nItemIndex, sCurrDir, nLenCurDir, TRUE ) ) continue; ASSERT( !sDisplayName.IsEmpty() ); UINT nCmdID = ID_FILE_MRU_FIRST + nItemIndex; ASSERT( nCmdID <= ID_FILE_MRU_LAST ); CExtCmdItem * pCmdItem = g_CmdManager->CmdGetPtr( g_CmdManager->ProfileNameFromWnd( m_hWndCmdReciever ), nCmdID ); if( pCmdItem == NULL ) pCmdItem = g_CmdManager->CmdAllocPtr( g_CmdManager->ProfileNameFromWnd( m_hWndCmdReciever ), nCmdID ); ASSERT( pCmdItem != NULL ); if( pCmdItem == NULL ) return false; int nDisplayIndex = nItemIndex+1; if( nDisplayIndex < 10 ) pCmdItem->m_sMenuText.Format( _T("&%d %s"), nDisplayIndex, sDisplayName ); else pCmdItem->m_sMenuText.Format( _T("%d&%d %s"), nDisplayIndex/10, nDisplayIndex%10, sDisplayName ); #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) CExtLocalResourceHelper _LRH; #endif // #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) CExtSafeString sRecentFileFmt1,sRecentFileFmt2; if( !sRecentFileFmt1.LoadString(IDS_RECENT_FILE_FMT_1) ) { #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) ASSERT( FALSE ); #endif // #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) sRecentFileFmt1 = _T("Recent file %d"); } if( !sRecentFileFmt2.LoadString(IDS_RECENT_FILE_FMT_2) ) { #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) ASSERT( FALSE ); #endif // #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) sRecentFileFmt2 = _T("Recent file %d (\"%s\")"); } pCmdItem->m_sToolbarText.Format( (LPCTSTR)sRecentFileFmt1, nItemIndex + 1 ); pCmdItem->m_sTipTool.Format( (LPCTSTR)sRecentFileFmt2, nItemIndex + 1, sDisplayName ); pCmdItem->m_sTipStatus = pCmdItem->m_sTipTool; BOOL bInsRetVal = ItemInsert( nCmdID, nMruUpdateIndex + nItemIndex ); if( !bInsRetVal ) { ASSERT( FALSE ); return false; } nMruInsertCount++; } // for( nItemIndex=0; nItemIndex<nRecentCount; nItemIndex++ ) } // can be null !? if( nMruInsertCount > 0 ) { if( !ItemInsert( ID_SEPARATOR, nMruUpdateIndex + nMruInsertCount ) ) { ASSERT( FALSE ); return false; } nMruInsertCount++; } // if( nMruInsertCount > 0 ) } // insert recently opened file items _SyncItems(); return true; } void CExtPopupMenuWnd::_GetClientRect(RECT * pRectClient) { ASSERT_VALID( this ); ASSERT( pRectClient != NULL ); ASSERT( GetSafeHwnd() != NULL ); *pRectClient = m_rcClient; ASSERT( pRectClient->top <= pRectClient->bottom ); ASSERT( pRectClient->left <= pRectClient->right ); } BOOL CExtPopupMenuWnd::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { ASSERT_VALID( this ); if( _FindHelpMode() ) { SetCursor( afxData.hcurHelp ); return TRUE; } CPoint ptCursor; if( ItemGetCount() > 0 && ::GetCursorPos(&ptCursor) ) { ScreenToClient( &ptCursor ); int nIndex = _HitTest( ptCursor ); if( nIndex >= 0 ) { MENUITEMDATA & mi = _GetItemRef( nIndex ); if( (! mi.IsExtraMark() ) && mi.IsInplaceEdit() && mi.IsAllowInplaceEditActivation() && (! _FindHelpMode() ) ) { CRect rcItem; _GetItemRect( nIndex, rcItem ); #if (!defined __EXT_MFC_NO_CUSTOMIZE) #if (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD) if( _FindCustomizeMode() ) { ASSERT_VALID( mi.GetCmdNode() ); if( mi.IsSelected() && (mi.GetCmdNode()->GetFlags() & __ECTN_TBB_RESIZABLE) != 0 ) { // if button can be resized int nDdWidth = g_PaintManager->GetDropDividerMerics().cx / 2; if( nDdWidth < 2 ) nDdWidth = 2; CRect rcH( rcItem ); rcH.right = rcH.left + nDdWidth; bool bSetCursor = false; if( rcH.PtInRect(ptCursor) ) bSetCursor = true; else { rcH = rcItem; rcH.left = rcH.right - nDdWidth; if( rcH.PtInRect(ptCursor) ) bSetCursor = true; } // else from if( rcH.PtInRect(ptCursor) ) if( bSetCursor ) { #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) CExtLocalResourceHelper _LRH; CWinApp * pApp = ::AfxGetApp(); ASSERT_VALID( pApp ); HCURSOR hCursor = pApp->LoadCursor( MAKEINTRESOURCE( IDC_EXT_RESIZE_H1 ) ); if( hCursor == NULL ) { ASSERT( FALSE ); hCursor = ::LoadCursor( NULL, IDC_SIZEWE ); } // if( hCursor == NULL ) #else // if - (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) HCURSOR hCursor = ::LoadCursor( NULL, IDC_SIZEWE ); #endif // if NOT - (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) ASSERT( hCursor != NULL ); ::SetCursor( hCursor ); return TRUE; } // if( bSetCursor ) } // if button can be resized } // if( _FindCustomizeMode() ) else #endif // (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD) #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) { CRect rcInplaceCtrl = mi.AdjustInplaceEditRect( rcItem ); if( rcInplaceCtrl.PtInRect(ptCursor) ) { HCURSOR hCursor = ::LoadCursor( NULL, IDC_IBEAM ); SetCursor( hCursor ); return TRUE; } // if( rcInplaceCtrl.PtInRect(ptCursor) ) } // else from if( _FindCustomizeMode() ) } } // if( nIndex >= 0 ) } // if( ItemGetCount() > 0 && ::GetCursorPos(&ptCursor) ) return CExtPopupBaseWnd::OnSetCursor(pWnd, nHitTest, message); } int CExtPopupMenuWnd::_HitTest( const CPoint & point, bool * p_bInplaceControlArea, // = NULL bool * p_bInplaceDropDownArea // = NULL ) { ASSERT_VALID( this ); if( p_bInplaceControlArea != NULL ) *p_bInplaceControlArea = false; if( p_bInplaceDropDownArea != NULL ) *p_bInplaceDropDownArea = false; if( GetSafeHwnd() == NULL ) return IDX_NOTHING; CRect rcClient; _GetClientRect( &rcClient ); if( !rcClient.PtInRect(point) ) return IDX_NOTHING; if( m_bScrollingAvailable ) { CRect rcItem; if( m_nDyScrollOffset != 0 ) { _GetItemRect(IDX_SCROLL_TOP,rcItem); if( rcItem.PtInRect(point) ) return IDX_SCROLL_TOP; } int nMaxScrollPos = _GetMaxScrollPos(); if( m_nDyScrollOffset != nMaxScrollPos ) { _GetItemRect(IDX_SCROLL_BOTTOM,rcItem); if( rcItem.PtInRect(point) ) return IDX_SCROLL_BOTTOM; } } if( m_bExpandAvailable ) { CRect rcExpand; _GetItemRect(IDX_EXPAND,rcExpand); if( rcExpand.PtInRect(point) ) return IDX_EXPAND; } //int nMenuBorderSize = // g_PaintManager->GetMenuBorderSize(); //int y = m_nDyScrollOffset + nMenuBorderSize; INT iter = 0; int nIndex = 0; for( ; iter < m_items_all.GetSize(); iter++,nIndex++ ) { MENUITEMDATA & mi = m_items_all[ iter ]; if( !mi.IsDisplayed() ) continue; CRect rcItem; _GetItemRect( nIndex, rcItem ); if( rcItem.PtInRect(point) ) { int nRetIndex = mi.GetIndex(); ASSERT( nRetIndex >= 0 && nRetIndex < m_items_all.GetSize() ); if( ( p_bInplaceControlArea != NULL || p_bInplaceDropDownArea != NULL ) && mi.IsInplaceEdit() ) { CRect rcInplaceCtrl = mi.AdjustInplaceEditRect( rcItem ); if( p_bInplaceControlArea != NULL ) { if( rcInplaceCtrl.PtInRect(point) ) *p_bInplaceControlArea = true; } if( p_bInplaceDropDownArea != NULL && mi.IsPopup() ) { rcInplaceCtrl.left = rcInplaceCtrl.right; rcInplaceCtrl.right += ::GetSystemMetrics(SM_CXHTHUMB); if( rcInplaceCtrl.PtInRect(point) ) *p_bInplaceDropDownArea = true; } } return nRetIndex; } } // for( ; iter < m_items_all.GetSize(); iter++,nIndex++ ) return IDX_NOTHING; }; BEGIN_MESSAGE_MAP(CExtPopupMenuWnd, CExtPopupBaseWnd) //{{AFX_MSG_MAP(CExtPopupMenuWnd) ON_WM_CANCELMODE() ON_WM_TIMER() ON_WM_ACTIVATEAPP() ON_WM_SHOWWINDOW() ON_WM_SETCURSOR() //}}AFX_MSG_MAP ON_WM_MOUSEMOVE() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_LBUTTONDBLCLK() ON_WM_MBUTTONDOWN() ON_WM_MBUTTONUP() ON_WM_MBUTTONDBLCLK() ON_WM_RBUTTONDOWN() ON_WM_RBUTTONUP() ON_WM_RBUTTONDBLCLK() ON_WM_KEYDOWN() ON_WM_KEYUP() ON_WM_SYSKEYDOWN() ON_WM_SYSKEYUP() ON_WM_SYSDEADCHAR() ON_WM_CHAR() END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CExtPopupMenuWnd message handlers BOOL CExtPopupMenuWnd::LoadMenu( HWND hWndCmdRecv, UINT nIDResource, bool bPopupMenu // = true ) { ASSERT_VALID( this ); CMenu menu; if( !menu.LoadMenu(nIDResource) ) { ASSERT( FALSE ); return FALSE; } return UpdateFromMenu( hWndCmdRecv, &menu, bPopupMenu ); } BOOL CExtPopupMenuWnd::UpdateMdiWindowsMenu( CWnd * pWndStartSearchMdiFrameWnd // = NULL ) { ASSERT_VALID( this ); ASSERT( m_hWndCmdReciever != NULL ); ASSERT( ::IsWindow(m_hWndCmdReciever) ); CMDIFrameWnd * pFrame = NULL; CWnd * pWnd = (pWndStartSearchMdiFrameWnd != NULL) ? pWndStartSearchMdiFrameWnd : FromHandle(m_hWndCmdReciever) // ::AfxGetMainWnd() ; while( true ) { ASSERT( pWnd != NULL ); ASSERT_VALID( pWnd ); pFrame = DYNAMIC_DOWNCAST( CMDIFrameWnd, pWnd ); if( pFrame != NULL ) break; pWnd = pWnd->GetParentFrame(); if( pWnd == NULL ) return FALSE; } // while( true ) if( pFrame == NULL ) return FALSE; int nItemIndex = ItemGetCount(); if( nItemIndex > 0 ) { MENUITEMDATA & mi = _GetItemRef(nItemIndex-1); if( !mi.IsSeparator() ) { ItemInsert(ID_SEPARATOR); nItemIndex++; ASSERT( nItemIndex == ItemGetCount() ); } } HWND m_hWndMDIClient = pFrame->m_hWndMDIClient; ASSERT( m_hWndMDIClient != NULL ); ASSERT( ::IsWindow(m_hWndMDIClient) ); HWND hWndActiveChildFrame = (HWND)::SendMessage( m_hWndMDIClient, WM_MDIGETACTIVE, 0, NULL ); int nCmdID = __ID_MDIWNDLIST_FIRST; for( int iWin=1; true; iWin++,nCmdID++ ) { HWND hWndChildFrame = ::GetDlgItem(m_hWndMDIClient, nCmdID); if( hWndChildFrame == NULL ) break; if( iWin <= __ID_MDIWNDLIST_COUNT ) { // if head of MDI windows list ASSERT( ::IsWindow(hWndChildFrame) ); CString sWinName( _T("") ); CWnd::FromHandle( hWndChildFrame )-> GetWindowText( sWinName ); CExtCmdItem * pCmdItem = g_CmdManager->CmdGetPtr( g_CmdManager->ProfileNameFromWnd( pWndStartSearchMdiFrameWnd->GetSafeHwnd() ), nCmdID ); if( pCmdItem == NULL ) pCmdItem = g_CmdManager->CmdAllocPtr( g_CmdManager->ProfileNameFromWnd( pWndStartSearchMdiFrameWnd->GetSafeHwnd() ), nCmdID ); ASSERT( pCmdItem != NULL ); if( pCmdItem == NULL ) return FALSE; pCmdItem->m_sMenuText.Format( _T("&%d %s"), iWin, sWinName ); pCmdItem->m_sToolbarText = pCmdItem->m_sMenuText; #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) CExtLocalResourceHelper _LRH; #endif // #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) CExtSafeString sDocumentNameFmt; if( !sDocumentNameFmt.LoadString(IDS_DOCUMENT_NAME_FMT) ) { #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) ASSERT( FALSE ); #endif // #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) sDocumentNameFmt = _T("Document \"%s\""); } pCmdItem->m_sTipTool.Format( (LPCTSTR)sDocumentNameFmt, sWinName ); pCmdItem->m_sTipStatus = pCmdItem->m_sTipTool; bool bRadio = (hWndChildFrame == hWndActiveChildFrame) ? true : false; pCmdItem->StateSetRadio( bRadio ); if( !ItemInsert(nCmdID) ) { ASSERT( FALSE ); return FALSE; } MENUITEMDATA & mi = ItemGetInfo( ItemGetCount()-1 ); mi.Radio( bRadio ); } // if head of MDI windows list else { // MDI windows list enough long, trim it if( !ItemInsert(TYPE_SEPARATOR) ) { ASSERT( FALSE ); return FALSE; } HWND hWndSearch = pWndStartSearchMdiFrameWnd->GetSafeHwnd(); ASSERT( hWndSearch != NULL ); ASSERT( ::IsWindow(hWndSearch) ); CExtCmdItem * pCmdItem = g_CmdManager->CmdGetPtr( g_CmdManager->ProfileNameFromWnd( hWndSearch ), __ID_MDIWND_DLGWINDOWS ); if( pCmdItem == NULL ) pCmdItem = g_CmdManager->CmdAllocPtr( g_CmdManager->ProfileNameFromWnd( hWndSearch ), __ID_MDIWND_DLGWINDOWS ); ASSERT( pCmdItem != NULL ); if( pCmdItem == NULL ) return FALSE; #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) CExtLocalResourceHelper _LRH; #endif // #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) CExtSafeString sMoreWindows,sManageWindows; if( !sMoreWindows.LoadString(IDS_MDI_MORE_WINDOWS) ) { #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) ASSERT( FALSE ); #endif // #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) sMoreWindows = _T("More Windows"); } if( !sManageWindows.LoadString(IDS_MDI_MANAGE_OPENED_WINDOWS) ) { #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) ASSERT( FALSE ); #endif // #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) sManageWindows = _T("Manage opened document windows"); } pCmdItem->m_sMenuText = sMoreWindows; pCmdItem->m_sToolbarText = pCmdItem->m_sMenuText; pCmdItem->m_sTipTool = sManageWindows; pCmdItem->m_sTipStatus = pCmdItem->m_sTipTool; if( !ItemInsert(nCmdID) ) { ASSERT( FALSE ); return FALSE; } break; } // MDI windows list enough long, trim it } // for( int iWin=1; true; iWin++,nCmdID++ ) _SyncItems(); return TRUE; } HMENU CExtPopupMenuWnd::ExportToMenu( BOOL bDeep // = TRUE ) const { ASSERT_VALID( this ); CMenu menu; if( !menu.CreatePopupMenu() ) { ASSERT( FALSE ); return NULL; } OSVERSIONINFO ov; ov.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); VERIFY( ::GetVersionEx( &ov ) ); bool bStupidNT4XX = ( ( ov.dwPlatformId == VER_PLATFORM_WIN32_NT ) && ( ov.dwMajorVersion < 5 ) ); int nCount = ItemGetCount(); for( int nItem = 0; nItem < nCount; nItem++ ) { const MENUITEMDATA & mi = _GetItemRef( nItem ); if( mi.IsPopup() ) { CExtSafeString sMiText( mi.GetText() ); CExtSafeString sMiAccelText( mi.GetAccelText() ); if( !sMiAccelText.IsEmpty() ) { sMiText += _T("\t"); sMiText += sMiAccelText; } const CExtPopupMenuWnd * pPopup = mi.GetPopup(); ASSERT( pPopup != NULL ); HMENU hPopupData; if( bDeep ) hPopupData = pPopup->ExportToMenu(); else hPopupData = ::CreatePopupMenu(); if( ( ! (::IsMenu(hPopupData)) ) || (! menu.AppendMenu( MF_STRING|MF_POPUP, UINT(hPopupData), sMiText ) ) ) { ASSERT( FALSE ); //continue; } if( bStupidNT4XX ) { VERIFY( ::DestroyMenu( hPopupData ) ); } continue; } // if( mi.IsPopup() ) if( mi.IsSeparator() ) { VERIFY( menu.AppendMenu( MF_SEPARATOR ) ); continue; } // if( mi.IsSeparator() ) CExtSafeString sMiText( mi.GetText() ); CExtSafeString sMiAccelText( mi.GetAccelText() ); if( !sMiAccelText.IsEmpty() ) { sMiText += _T("\t"); sMiText += sMiAccelText; } VERIFY( menu.AppendMenu( MF_STRING, mi.GetCmdID(), sMiText ) ); } // for( int nItem = 0; nItem < nCount; nItem++ ) return menu.Detach(); } BOOL CExtPopupMenuWnd::UpdateFromMenu( HWND hWndCmdRecv, CMenu * pBuildMenu, bool bPopupMenu, // = true bool bTopLevel // = true ) { ASSERT_VALID( this ); if( hWndCmdRecv != NULL ) m_hWndCmdReciever = hWndCmdRecv; ASSERT( m_hWndCmdReciever != NULL ); ASSERT( ::IsWindow(m_hWndCmdReciever) ); if( pBuildMenu == NULL || (!(::IsMenu(pBuildMenu->GetSafeHmenu()))) ) { ASSERT( FALSE ); return false; } if( bPopupMenu ) { pBuildMenu = pBuildMenu->GetSubMenu(0); if( pBuildMenu == NULL || (!(::IsMenu(pBuildMenu->GetSafeHmenu()))) ) { ASSERT( FALSE ); return false; } } if( !g_CmdManager->UpdateFromMenu( g_CmdManager->ProfileNameFromWnd( m_hWndCmdReciever ), pBuildMenu->GetSafeHmenu() ) ) { ASSERT( FALSE ); return false; } if( !_BuildItems( pBuildMenu, bTopLevel ) ) return FALSE; return TRUE; } #if (!defined __EXT_MFC_NO_CUSTOMIZE) bool CExtPopupMenuWnd::UpdateFromCmdTree( HWND hWndCmdRecv, CExtCustomizeCmdTreeNode * pNode, bool bTopLevel // = true ) { ASSERT_VALID( this ); ASSERT_VALID( pNode ); m_pNode = pNode; if( hWndCmdRecv != NULL ) m_hWndCmdReciever = hWndCmdRecv; ASSERT( m_hWndCmdReciever != NULL ); ASSERT( ::IsWindow(m_hWndCmdReciever) ); __EXT_MFC_SAFE_LPCTSTR strProfileName = g_CmdManager->ProfileNameFromWnd( m_hWndCmdReciever ); bool bCustomizeMode = false; CExtCustomizeSite * pSite = CExtCustomizeSite::GetCustomizeSite( m_hWndCmdReciever ); if( pSite != NULL ) bCustomizeMode = pSite->IsCustomizeMode(); INT iter = 0; for( ; iter < m_items_all.GetSize(); iter++) { MENUITEMDATA & mi = m_items_all[ iter ]; if( mi.IsPopup() ) { mi.GetPopup()->m_hWndCmdReciever = m_hWndCmdReciever; mi.GetPopup()->_OnCancelMode(); VERIFY( mi.GetPopup()->_BuildItems( NULL, false ) ); mi.DestroyPopup(); } } // for( ; iter < m_items_all.GetSize(); iter++) m_items_all.RemoveAll(); if( pNode == NULL ) return true; ASSERT_VALID( pNode ); m_bTopLevel = bTopLevel; if( m_bTopLevel ) m_pWndParentMenu = NULL; // build items loop int nMruUpdateIndex = -1, nInsertedIndex = 0; int nMenuItemCount = pNode->GetNodeCount(); m_items_all.RemoveAll(); for( int nItemIndex = 0; nItemIndex < nMenuItemCount; nItemIndex++ ) { CExtCustomizeCmdTreeNode * pChildNode = pNode->ElementAt( nItemIndex ); ASSERT_VALID( pChildNode ); if( pChildNode->GetFlags() & __ECTN_GROUP_START ) { VERIFY( ItemInsert( CExtPopupMenuWnd::TYPE_SEPARATOR, nInsertedIndex++ ) ); } // if( pChildNode->GetFlags() & __ECTN_GROUP_START ) UINT nMenuItemID = pChildNode->GetCmdID( false ); if( ID_FILE_MRU_FIRST <= nMenuItemID && nMenuItemID <= ID_FILE_MRU_LAST && (! bCustomizeMode ) ) { if( nMruUpdateIndex < 0 ) nMruUpdateIndex = nInsertedIndex; continue; } MENUITEMDATA mi; mi.SetCmdReciever( m_hWndCmdReciever ); VERIFY( mi.UpdateFromCmdTree( m_hWndCmdReciever, pChildNode, nInsertedIndex ) ); ASSERT( !mi.IsSeparator() ); CExtCmdItem * pCmdItem = NULL; if( mi.IsPopup() ) { mi.GetPopup()->m_hWndCmdReciever = m_hWndCmdReciever; mi.GetPopup()->UpdateFromCmdTree( hWndCmdRecv, pChildNode, false ); mi.GetPopup()->m_pWndParentMenu = this; } // if( mi.IsPopup() ) else { pCmdItem = g_CmdManager->CmdGetPtr( strProfileName, mi.GetCmdID() ); mi.SetAccelText( pCmdItem->m_sAccelText ); } // else from if( mi.IsPopup() ) mi.SetText( pChildNode->GetTextInMenu( pCmdItem ) ); mi.AccelCharInit(); mi.MeasureItem(); _InsertItem( -1, mi ); nInsertedIndex++; } // for( int nItemIndex = 0; nItemIndex < nMenuItemCount; nItemIndex++ ) int nMruInsertCount = 0; if( nMruUpdateIndex >= 0 ) { // insert recently opened file items //ASSERT( nMruUpdateIndex <= nMenuItemCount ); CRecentFileList * pRecentFileList = InternalFriendlyWinApp::_GetFriendlyApp()-> _GetRecentFileList(); if( pRecentFileList != NULL ) { // can be null !? int nRecentCount = pRecentFileList->GetSize(); TCHAR sCurrDir[_MAX_PATH+1]; ::memset(sCurrDir,0,sizeof(sCurrDir)); ::GetCurrentDirectory(_MAX_PATH,sCurrDir); int nLenCurDir = _tcslen(sCurrDir); for( nItemIndex=0; nItemIndex<nRecentCount; nItemIndex++ ) { CExtSafeString sDisplayName( _T("") ); if( !pRecentFileList->GetDisplayName( *((CString *)&sDisplayName), nItemIndex, sCurrDir, nLenCurDir, TRUE ) ) continue; ASSERT( !sDisplayName.IsEmpty() ); UINT nCmdID = ID_FILE_MRU_FIRST + nItemIndex; ASSERT( nCmdID <= ID_FILE_MRU_LAST ); CExtCmdItem * pCmdItem = g_CmdManager->CmdGetPtr( g_CmdManager->ProfileNameFromWnd( m_hWndCmdReciever ), nCmdID ); if( pCmdItem == NULL ) pCmdItem = g_CmdManager->CmdAllocPtr( g_CmdManager->ProfileNameFromWnd( m_hWndCmdReciever ), nCmdID ); ASSERT( pCmdItem != NULL ); if( pCmdItem == NULL ) return false; int nDisplayIndex = nItemIndex+1; if( nDisplayIndex < 10 ) pCmdItem->m_sMenuText.Format( _T("&%d %s"), nDisplayIndex, sDisplayName ); else pCmdItem->m_sMenuText.Format( _T("%d&%d %s"), nDisplayIndex/10, nDisplayIndex%10, sDisplayName ); #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) CExtLocalResourceHelper _LRH; #endif // #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) CExtSafeString sRecentFileFmt1,sRecentFileFmt2; if( !sRecentFileFmt1.LoadString(IDS_RECENT_FILE_FMT_1) ) { #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) ASSERT( FALSE ); #endif // #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) sRecentFileFmt1 = _T("Recent file %d"); } if( !sRecentFileFmt2.LoadString(IDS_RECENT_FILE_FMT_2) ) { #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) ASSERT( FALSE ); #endif // #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) sRecentFileFmt2 = _T("Recent file %d (\"%s\")"); } pCmdItem->m_sToolbarText.Format( (LPCTSTR)sRecentFileFmt1, nItemIndex + 1 ); pCmdItem->m_sTipTool.Format( (LPCTSTR)sRecentFileFmt2, nItemIndex + 1, sDisplayName ); pCmdItem->m_sTipStatus = pCmdItem->m_sTipTool; BOOL bInsRetVal = ItemInsert( nCmdID, nMruUpdateIndex + nItemIndex ); if( !bInsRetVal ) { ASSERT( FALSE ); return false; } nMruInsertCount++; } // for( nItemIndex=0; nItemIndex<nRecentCount; nItemIndex++ ) } // can be null !? /* if( nMruInsertCount > 0 ) { if( nMruUpdateIndex > 0 && (! _GetItemRef( nMruUpdateIndex - 1 ).IsSeparator() ) ) { if( !ItemInsert( ID_SEPARATOR, nMruUpdateIndex ) ) { ASSERT( FALSE ); return false; } nMruInsertCount++; nMruUpdateIndex++; } if( ( nMruUpdateIndex + nMruInsertCount ) < m_items_all.GetSize() && (! _GetItemRef( nMruUpdateIndex + nMruInsertCount ).IsSeparator() ) ) { if( !ItemInsert( ID_SEPARATOR, nMruUpdateIndex + nMruInsertCount ) ) { ASSERT( FALSE ); return false; } nMruInsertCount++; } } // if( nMruInsertCount > 0 ) */ if( nMruInsertCount == 0 && nMruUpdateIndex > 0 && nMruUpdateIndex < (ItemGetCount()-1) && _GetItemRef( nMruUpdateIndex ).IsSeparator() && _GetItemRef( nMruUpdateIndex-1 ).IsSeparator() ) m_items_all.RemoveAt( nMruUpdateIndex ); } // insert recently opened file items _SyncItems(); return true; } #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) CExtPopupMenuSite & CExtPopupMenuWnd::GetSite() const { return CExtPopupMenuSite::g_DefPopupMenuSite; } CExtPopupMenuWnd * CExtPopupMenuWnd::GetTrackingMenu() { CExtPopupMenuWnd * pPopup = CExtPopupMenuSite::g_DefPopupMenuSite.GetInstance(); if( !(::IsWindow(pPopup->GetSafeHwnd())) ) return NULL; ASSERT_VALID( pPopup ); return pPopup; } void CExtPopupMenuWnd::CancelMenuTracking() { if( !CExtPopupMenuSite::g_DefPopupMenuSite.IsEmpty() && !CExtPopupMenuSite::g_DefPopupMenuSite.IsShutdownMode() ) { CExtPopupMenuSite::g_DefPopupMenuSite.DoneInstance(); ASSERT( CExtPopupMenuSite::g_DefPopupMenuSite.IsEmpty() ); ASSERT( !CExtPopupMenuSite::g_DefPopupMenuSite.IsShutdownMode() ); } } BOOL CExtPopupMenuWnd::IsMenuTracking() { if( CExtPopupMenuSite::g_DefPopupMenuSite.IsEmpty() //|| CExtPopupMenuSite::g_DefPopupMenuSite.GetCapture() == NULL ) return FALSE; return TRUE; } BOOL CExtPopupMenuWnd::TrackPopupMenu( DWORD dwTrackFlags, int x, int y, LPCRECT lpRect, // = NULL LPVOID pCbPaintCombinedCookie, // = NULL pCbPaintCombinedContent pCbPaintCombinedContent, // = NULL UINT * lpnResultCmdID, // = NULL bool bCookieIsObject // = false ) { ASSERT_VALID( this ); if( lpnResultCmdID != NULL ) *lpnResultCmdID = 0; ASSERT( m_hWndCmdReciever != NULL ); ASSERT( ::IsWindow(m_hWndCmdReciever) ); CWnd * pWndCmdReciever = CWnd::FromHandlePermanent( m_hWndCmdReciever ); if( pWndCmdReciever != NULL && CExtControlBar::FindHelpMode( pWndCmdReciever ) ) dwTrackFlags |= TPMX_HELP_CTX_MODE; #if (!defined __EXT_MFC_NO_CUSTOMIZE) m_pCustomizeSite = CExtCustomizeSite::GetCustomizeSite( m_hWndCmdReciever ); #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) ASSERT( (dwTrackFlags&(TPMX_CUSTOMIZE_MODE|TPMX_HELP_CTX_MODE)) != (TPMX_CUSTOMIZE_MODE|TPMX_HELP_CTX_MODE) ); if( (dwTrackFlags&TPMX_CUSTOMIZE_MODE) != 0 ) { dwTrackFlags &= ~ ( TPMX_COMBINE_MASK |TPMX_SELECT_ANY |TPMX_DO_MESSAGE_LOOP |TPMX_OWNERDRAW_FIXED ); dwTrackFlags |= TPMX_NO_SHADOWS |TPMX_NO_HIDE_RARELY |TPMX_NO_WM_COMMAND |TPMX_NO_CMD_UI; } // if( (dwTrackFlags&TPMX_CUSTOMIZE_MODE) != 0 ) HWND hWndCurrentFocus = ::GetFocus(); if( hWndCurrentFocus != NULL ) { CWnd * pWndTest = CWnd::FromHandlePermanent( hWndCurrentFocus ); if( pWndTest == NULL ) { HWND hWnd = ::GetParent( hWndCurrentFocus ); if( hWnd != NULL ) pWndTest = CWnd::FromHandlePermanent( hWnd ); } // if( pWndTest == NULL ) if( pWndTest != NULL ) { CComboBox * pComboTest = DYNAMIC_DOWNCAST( CComboBox, pWndTest ); if( pComboTest == NULL ) { pWndTest = pWndTest->GetParent(); if( pWndTest != NULL ) { pComboTest = DYNAMIC_DOWNCAST( CComboBox, pWndTest ); } } // if( pComboTest == NULL ) if( pComboTest != NULL && (pComboTest->GetStyle() & (CBS_DROPDOWN|CBS_DROPDOWNLIST)) != 0 && pComboTest->GetDroppedState() ) pComboTest->ShowDropDown( FALSE ); } // if( pWndTest != NULL ) } // if( hWndCurrentFocus != NULL ) CExtPopupMenuSite & _site = GetSite(); bool bSiteWasEmpty = _site.IsEmpty(); if( !bSiteWasEmpty ) { if( _site.IsShutdownMode() ) return FALSE; _site.DoneInstance(); } //bool bCaptureChanged = false; HWND hWndCapture = ::GetCapture(); CWnd * pWndCapture = FromHandlePermanent( hWndCapture ); if( pWndCapture != NULL ) { ReleaseCapture(); if( ::IsWindow(hWndCapture) ) { ASSERT_VALID( pWndCapture ); pWndCapture->SendMessage(WM_CANCELMODE); } // bCaptureChanged = true; } ASSERT( _site.IsEmpty() ); ASSERT( !_site.IsShutdownMode() ); ASSERT( m_hWndCmdReciever != NULL ); ASSERT( ::IsWindow(m_hWndCmdReciever) ); // if( !bSiteWasEmpty // || CExtToolControlBar::g_bMenuTracking // || bCaptureChanged // ) // { // PassMsgLoop( CExtPopupBaseWnd::g_bEnableOnIdleCalls ); // if( ! ::IsWindow(m_hWndCmdReciever) ) // return FALSE; // } // if( !_site.IsEmpty() ) // return FALSE; ASSERT( m_bTopLevel ); ASSERT( _site.IsEmpty() ); if( (dwTrackFlags&TPMX_CUSTOMIZE_MODE) == 0 ) { _site.SetInstance( this ); if( lpnResultCmdID != NULL ) _site.SetTargetCmdIdPtr( lpnResultCmdID ); } m_dwTrackFlags = dwTrackFlags; if( (dwTrackFlags&TPMX_CUSTOMIZE_MODE) == 0 ) _UpdateCmdUI(); if( ! _TrackPopupMenu( dwTrackFlags, x, y, lpRect, pCbPaintCombinedCookie, pCbPaintCombinedContent, bCookieIsObject ) ) { //ASSERT( FALSE ); if( (dwTrackFlags&TPMX_CUSTOMIZE_MODE) == 0 ) { _site.DoneInstance(); ASSERT( _site.IsEmpty() ); ASSERT( !_site.IsShutdownMode() ); } // if( (dwTrackFlags&TPMX_CUSTOMIZE_MODE) == 0 ) return FALSE; } if( (dwTrackFlags&TPMX_DO_MESSAGE_LOOP) == 0 ) return TRUE; // do popup menu message loop while( IsMenuTracking() ) { WaitMessage(); HWND hWndThis = GetSafeHwnd(); CExtPopupMenuWnd::PassMsgLoop( CExtPopupBaseWnd::g_bEnableOnIdleCalls ); if( !::IsWindow(hWndThis) ) break; } // while( IsMenuTracking() ) if( !CExtToolControlBar::g_bMenuTracking ) { _site.DoneInstance(); ASSERT( _site.IsEmpty() ); ASSERT( !_site.IsShutdownMode() ); } return TRUE; } void CExtPopupMenuWnd::PassMsgLoop( bool bEnableOnIdleCalls ) { #ifdef _USRDLL // If this is a DLL, need to set up MFC state AFX_MANAGE_STATE(AfxGetStaticModuleState()); #endif MSG msg; // Process all the messages in the message queue while( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) ) { if( !AfxGetThread()->PumpMessage() ) { PostQuitMessage(0); return; } // if( !AfxGetThread()->PumpMessage() ) } // while( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) ) if( bEnableOnIdleCalls ) { for( LONG nIdleCounter = 0L; ::AfxGetThread()->OnIdle(nIdleCounter); nIdleCounter ++ ); } } CSize CExtPopupMenuWnd::_CalcTrackSize() { ASSERT_VALID( this ); int nMenuShadowSize = _GetPopupShadowSize(); int nMenuBorderSize = g_PaintManager->GetMenuBorderSize(); int nXtraSz = nMenuBorderSize*2 + nMenuShadowSize; CSize _size( m_sizeFullItems ); if( m_bExpandAvailable ) _size.cy += _GetSpecBtnHeight(); // xpand btn _size += CSize( nXtraSz + m_nLeftAreaWidth, nXtraSz ); if( _size.cx < (nMenuShadowSize*2 + 10) ) _size.cx = nMenuShadowSize*2 + 10; if( _size.cy < (nMenuShadowSize*2 + 10) ) _size.cy = nMenuShadowSize*2 + 10; return _size; } CRect CExtPopupMenuWnd::_CalcTrackRect() { ASSERT_VALID( this ); m_eCombineAlign = __CMBA_NONE; if( IsKeyPressed(VK_CONTROL) ) { int i=1; i; } CExtPaintManager::monitor_parms_t _mp; if( m_bExcludeAreaSpec ) CExtPaintManager::stat_GetMonitorParms( _mp, m_rcExcludeArea ); else if( m_pWndParentMenu != NULL ) { ASSERT_VALID( m_pWndParentMenu ); ASSERT( m_pWndParentMenu->GetSafeHwnd() != NULL ); ASSERT( ::IsWindow( m_pWndParentMenu->GetSafeHwnd() ) ); CExtPaintManager::stat_GetMonitorParms( _mp, m_pWndParentMenu ); } // else if( m_pWndParentMenu != NULL ) else CExtPaintManager::stat_GetMonitorParms( _mp, m_ptTrack ); CRect rcDesktop = g_bUseDesktopWorkArea ? _mp.m_rcWorkArea : _mp.m_rcMonitor ; CSize _size = _CalcTrackSize(); int nMenuShadowSize = _GetPopupShadowSize(); int nMenuBorderSize = g_PaintManager->GetMenuBorderSize(); int nGapShift = 0; if( !m_bCombineWithEA ) nGapShift = nMenuBorderSize + nMenuShadowSize; if( (m_dwTrackFlags&TPMX_ALIGN_MASK) == 0 && (!m_bCombineWithEA) ) { if( m_pWndParentMenu->GetSafeHwnd() != NULL ) { if( (m_pWndParentMenu->m_dwTrackFlags&TPMX_ALIGN_MASK) != 0 ) m_dwTrackFlags |= m_pWndParentMenu->m_dwTrackFlags& (~TPMX_ALIGN_MASK); else { CRect rc1; m_pWndParentMenu->GetWindowRect(&rc1); if( m_pWndParentMenu->m_pWndParentMenu->GetSafeHwnd() != NULL ) { CRect rc2; m_pWndParentMenu->m_pWndParentMenu->GetWindowRect(&rc2); int x1 = rc1.left + rc1.Width()/2; int x2 = rc2.left + rc2.Width()/2; if( x1 >= x2 ) m_dwTrackFlags |= TPMX_LEFTALIGN; else m_dwTrackFlags |= TPMX_RIGHTALIGN; } } } } CRect wr(m_ptTrack,_size); // wr.NormalizeRect(); int nCombineOffset = 0; if( m_bCombineWithEA ) { if( (m_dwTrackFlags&TPMX_ALIGN_MASK) == TPMX_TOPALIGN ) { nCombineOffset = 1; wr.OffsetRect(0,-nCombineOffset); } if( (m_dwTrackFlags&TPMX_ALIGN_MASK) == TPMX_LEFTALIGN ) { nCombineOffset = 1; wr.OffsetRect(-nCombineOffset,0); } if( (m_dwTrackFlags&TPMX_ALIGN_MASK) == TPMX_BOTTOMALIGN ) { nCombineOffset = -nMenuShadowSize - 1; wr.OffsetRect(0,-nCombineOffset); } if( (m_dwTrackFlags&TPMX_ALIGN_MASK) == TPMX_RIGHTALIGN ) { nCombineOffset = -nMenuShadowSize - 1; wr.OffsetRect(-nCombineOffset,0); } } // if( m_bCombineWithEA ) if(wr.bottom > rcDesktop.bottom) { if( m_bExcludeAreaSpec ) { wr.OffsetRect( 0, -wr.Height() + m_rcExcludeArea.Height() + nGapShift + (m_bCombineWithEA ? nMenuShadowSize : 0) ); } // if( m_bExcludeAreaSpec ) if(wr.bottom > rcDesktop.bottom) wr.OffsetRect( 0, m_bExcludeAreaSpec ? -(wr.bottom - rcDesktop.bottom) : - wr.Height() ); } // if(wr.bottom > rcDesktop.bottom) if(wr.top < rcDesktop.top) wr.OffsetRect( 0, rcDesktop.top - wr.top ); if(wr.right > rcDesktop.right) { if( !m_bTopLevel && m_bExcludeAreaSpec ) wr.OffsetRect( -wr.Width() - m_rcExcludeArea.Width(), 0 ); if(wr.right > rcDesktop.right) wr.OffsetRect( m_bExcludeAreaSpec ? -(wr.right - rcDesktop.right) : -wr.Width(), 0 ); } // if(wr.right > rcDesktop.right) if(wr.left < rcDesktop.left) { if( !m_bTopLevel && m_bExcludeAreaSpec ) wr.OffsetRect( wr.Width() + m_rcExcludeArea.Width(), 0 ); if(wr.left < rcDesktop.left) wr.OffsetRect( rcDesktop.left - wr.left, 0 ); } // if(wr.left < rcDesktop.left) if( m_bExcludeAreaSpec || m_bCombineWithEA ) { CRect rcIntersection; if( rcIntersection.IntersectRect( &wr, &m_rcExcludeArea ) || m_bCombineWithEA ) { // if need adjust with exclude area CRect rcFree(0,0,0,0); if( m_rcExcludeArea.left > rcDesktop.left ) rcFree.left = m_rcExcludeArea.left - rcDesktop.left; if( m_rcExcludeArea.right < rcDesktop.right ) rcFree.right = rcDesktop.right - m_rcExcludeArea.right; if( m_rcExcludeArea.top > rcDesktop.top ) rcFree.top = m_rcExcludeArea.top - rcDesktop.top; if( m_rcExcludeArea.bottom < rcDesktop.bottom ) rcFree.bottom = rcDesktop.bottom - m_rcExcludeArea.bottom; if( (m_dwTrackFlags&TPMX_ALIGN_MASK) == TPMX_LEFTALIGN && rcFree.right > wr.Width() ) wr.OffsetRect( wr.left - m_rcExcludeArea.right + (m_bCombineWithEA ? nCombineOffset : 0) , 0 ); if( (m_dwTrackFlags&TPMX_ALIGN_MASK) == TPMX_RIGHTALIGN && rcFree.left > wr.Width() ) wr.OffsetRect( m_rcExcludeArea.left - wr.right - (m_bCombineWithEA ? nCombineOffset : 0) , 0 ); // if( (m_dwTrackFlags&TPMX_ALIGN_MASK) // == TPMX_TOPALIGN // && rcFree.bottom > wr.Height() // ) // wr.OffsetRect( // 0, // wr.top - m_rcExcludeArea.bottom // + (m_bCombineWithEA ? // nCombineOffset : 0) // ); if( (m_dwTrackFlags&TPMX_ALIGN_MASK) == TPMX_TOPALIGN ) { if( rcFree.bottom > wr.Height() ) wr.OffsetRect( 0, wr.top - m_rcExcludeArea.bottom + (m_bCombineWithEA ? nCombineOffset : 0) ); else { if( ::IsWindow(GetSafeHwnd()) ) { CRect rcWndOld; GetWindowRect( &rcWndOld ); ShowWindow( SW_HIDE ); _FreeWinObjects(); HWND hWndThis = GetSafeHwnd(); bool bWasCreated = (hWndThis != NULL && ::IsWindow(hWndThis)) ? true : false; CExtPopupMenuWnd::PassMsgLoop( CExtPopupBaseWnd::g_bEnableOnIdleCalls ); if( bWasCreated && !::IsWindow(hWndThis) ) return CRect(0,0,0,0); if( !rcWndOld.IsRectEmpty() ) { CWnd * pWndTLP = GetTopLevelParent(); if( pWndTLP != NULL ) { ASSERT_VALID( pWndTLP ); if( pWndTLP->IsWindowVisible() ) { CRect rcTLP; pWndTLP->GetWindowRect( &rcTLP ); if( !rcTLP.IsRectEmpty() ) { CRect rcIntersection; if( rcIntersection.IntersectRect( &rcTLP, &rcWndOld ) ) pWndTLP->UpdateWindow(); } // if( !rcTLP.IsRectEmpty() ) } // if( pWndTLP->IsWindowVisible() ) } // if( pWndTLP != NULL ) } // if( !rcWndOld.IsRectEmpty() ) } m_dwTrackFlags &= ~TPMX_ALIGN_MASK; m_dwTrackFlags |= TPMX_BOTTOMALIGN; return _CalcTrackRect(); } } if( (m_dwTrackFlags&TPMX_ALIGN_MASK) == TPMX_BOTTOMALIGN && rcFree.top > wr.Height() ) wr.OffsetRect( 0, m_rcExcludeArea.top - wr.bottom - (m_bCombineWithEA ? nCombineOffset : 0) ); } // if need adjust with exclude area } // if( m_bExcludeAreaSpec || m_bCombineWithEA ) if(wr.right > rcDesktop.right) { wr.OffsetRect( -(wr.right - rcDesktop.right), 0 ); if( m_bTopLevel ) { m_bExcludeAreaSpec = false; m_bCombineWithEA = false; } } // if(wr.right > rcDesktop.right) if(wr.left < rcDesktop.left) { wr.OffsetRect( rcDesktop.left - wr.left, 0 ); if( m_bTopLevel ) { m_bExcludeAreaSpec = false; m_bCombineWithEA = false; } } // if(wr.left < rcDesktop.left) if(wr.bottom > rcDesktop.bottom) { wr.OffsetRect( 0, -(wr.bottom - rcDesktop.bottom) ); if( m_bTopLevel ) { m_bExcludeAreaSpec = false; m_bCombineWithEA = false; } } // if(wr.bottom > rcDesktop.bottom) if(wr.top < rcDesktop.top) { wr.OffsetRect( 0, rcDesktop.top - wr.top ); if( m_bTopLevel ) { m_bExcludeAreaSpec = false; m_bCombineWithEA = false; } } // if(wr.top < rcDesktop.top) if(wr.bottom > rcDesktop.bottom) { wr.bottom = rcDesktop.bottom; m_bScrollingAvailable = true; } if( m_bCombineWithEA ) { ASSERT( m_bExcludeAreaSpec ); if( wr.bottom == m_rcExcludeArea.top - nCombineOffset ) m_eCombineAlign = __CMBA_BOTTOM; if( wr.top == m_rcExcludeArea.bottom - nCombineOffset ) m_eCombineAlign = __CMBA_TOP; if( wr.left == m_rcExcludeArea.right - nCombineOffset ) m_eCombineAlign = __CMBA_LEFT; if( wr.right == m_rcExcludeArea.left - nCombineOffset ) m_eCombineAlign = __CMBA_RIGHT; if( m_eCombineAlign == __CMBA_NONE ) { m_bCombineWithEA = false; return _CalcTrackRect(); } // if( m_eCombineAlign == __CMBA_NONE ) // init window region if( m_rgnWnd.GetSafeHandle() != NULL ) { VERIFY( m_rgnWnd.DeleteObject() ); } CRect rcExcludeArea(m_rcExcludeArea); rcExcludeArea.InflateRect( 0, 0, nMenuShadowSize, nMenuShadowSize ); CRect rcFullWnd( min(wr.left,rcExcludeArea.left), min(wr.top,rcExcludeArea.top), max(wr.right,rcExcludeArea.right), max(wr.bottom,rcExcludeArea.bottom) ); if( !m_bTopLevel ) { if( m_eCombineAlign == __CMBA_LEFT || m_eCombineAlign == __CMBA_RIGHT ) rcExcludeArea.DeflateRect( 0, 0, 0, nMenuShadowSize ); else if( m_eCombineAlign == __CMBA_TOP || m_eCombineAlign == __CMBA_BOTTOM ) rcExcludeArea.DeflateRect( 0, 0, nMenuShadowSize, 0 ); } CRgn rgnAreaWnd,rgnAreaExclude; if( (!m_rgnWnd.CreateRectRgnIndirect( &rcFullWnd )) || (!rgnAreaExclude.CreateRectRgnIndirect( &rcExcludeArea )) || (!rgnAreaWnd.CreateRectRgnIndirect( &wr )) || m_rgnWnd.CombineRgn( &rgnAreaWnd, &rgnAreaExclude, RGN_OR ) == ERROR || m_rgnWnd.OffsetRgn( -rcFullWnd.TopLeft() ) == ERROR ) { if( m_rgnWnd.GetSafeHandle() != NULL ) { VERIFY( m_rgnWnd.DeleteObject() ); } m_bCombineWithEA = false; return _CalcTrackRect(); } ASSERT( m_rgnWnd.GetSafeHandle() != NULL ); // VERIFY( m_rgnWnd.DeleteObject() ); // VERIFY( // m_rgnWnd.CreateRectRgnIndirect( // &rcFullWnd // ) // ); m_rcClient = wr; m_rcClient.OffsetRect( -rcFullWnd.TopLeft() ); m_rcClient.DeflateRect( 0, 0, nMenuShadowSize, nMenuShadowSize ); ASSERT( m_rcClient.top <= m_rcClient.bottom ); ASSERT( m_rcClient.left <= m_rcClient.right ); if( !m_bTopLevel ) { if( m_eCombineAlign == __CMBA_RIGHT ) rcFullWnd.OffsetRect( nMenuShadowSize + 1, 0 ); else if( m_eCombineAlign == __CMBA_LEFT ) rcFullWnd.OffsetRect( -2, 0 ); } return rcFullWnd; } // if( m_bCombineWithEA ) m_rcClient = wr; m_rcClient.OffsetRect( -wr.TopLeft() ); m_rcClient.DeflateRect( 0, 0, nMenuShadowSize, nMenuShadowSize ); ASSERT( m_rcClient.top <= m_rcClient.bottom ); ASSERT( m_rcClient.left <= m_rcClient.right ); return wr; } BOOL CExtPopupMenuWnd::_TrackPopupMenu( DWORD dwTrackFlags, int x, int y, LPCRECT lpRect, LPVOID pCbPaintCombinedCookie, // = NULL pCbPaintCombinedContent pCbPaintCombinedContent, // = NULL bool bCookieIsObject // = false ) { ASSERT_VALID( this ); bool bForceExpandRarelyUsed = (dwTrackFlags&TPMX_NO_HIDE_RARELY) ? true : false; if( !g_bMenuExpanding ) bForceExpandRarelyUsed = true; ASSERT( m_hWndCmdReciever != NULL ); ASSERT( ::IsWindow(m_hWndCmdReciever) ); ASSERT( GetSafeHwnd() == NULL ); CExtPopupMenuSite & _site = GetSite(); if( (!_FindCustomizeMode()) && _site.IsTopPupup(this) ) { ASSERT( m_bTopLevel ); MsgPrepareMenuData_t _mpmd( this ); _mpmd.SendMessage( m_hWndCmdReciever ); if( _mpmd.m_bMenuCanceled ) return FALSE; if( _mpmd.m_bMenuChanged ) { _UpdateCmdUI(); } ASSERT( m_bTopLevel ); ASSERT( _site.IsTopPupup(this) ); } if( !_FindCustomizeMode() ) { // BLOCK: update system commands INT iter = 0; for(; iter < m_items_all.GetSize(); ++iter ) { MENUITEMDATA & mi = m_items_all[ iter ]; if( mi.IsSeparator() ) continue; UINT nCmdID = mi.GetCmdID(); if( !CExtCmdManager::IsSystemCommand(nCmdID)) continue; WINDOWPLACEMENT wndpl; ::memset(&wndpl,0,sizeof(WINDOWPLACEMENT)); wndpl.length = sizeof(WINDOWPLACEMENT); VERIFY( ::GetWindowPlacement( mi.GetCmdReciever(), &wndpl ) ); DWORD dwWndStyle = (DWORD) ::GetWindowLong( mi.GetCmdReciever(), GWL_STYLE ); DWORD dwWndExStyle = (DWORD) ::GetWindowLong( mi.GetCmdReciever(), GWL_EXSTYLE ); bool bSysCmdEnabled = false; switch( nCmdID ) { case SC_CLOSE: { bSysCmdEnabled = true; HMENU hSysMenu = ::GetSystemMenu( mi.GetCmdReciever(), FALSE ); MENUITEMINFO _mii; ::memset( &_mii, 0, sizeof(MENUITEMINFO) ); _mii.cbSize = sizeof(MENUITEMINFO); _mii.fMask = MIIM_STATE; if( hSysMenu != NULL && ::GetMenuItemInfo( hSysMenu, SC_CLOSE, FALSE, &_mii ) ) { if( (_mii.fState & MFS_DISABLED) != 0 ) bSysCmdEnabled = false; } // if( hSysMenu != NULL ... } break; case SC_SIZE: case SC_MOVE: if( wndpl.showCmd != SW_SHOWMINIMIZED && wndpl.showCmd != SW_SHOWMAXIMIZED ) bSysCmdEnabled = true; break; case SC_MINIMIZE: if( (dwWndStyle & WS_MINIMIZEBOX) != 0 && wndpl.showCmd != SW_SHOWMINIMIZED ) bSysCmdEnabled = true; break; case SC_MAXIMIZE: if( (dwWndStyle & WS_MAXIMIZEBOX) != 0 && wndpl.showCmd != SW_SHOWMAXIMIZED ) bSysCmdEnabled = true; break; case SC_RESTORE: if( (dwWndStyle & (WS_MINIMIZEBOX|WS_MAXIMIZEBOX)) != 0 && ( wndpl.showCmd == SW_SHOWMAXIMIZED || wndpl.showCmd == SW_SHOWMINIMIZED //||wndpl.showCmd == SW_SHOWNORMAL ) ) bSysCmdEnabled = true; break; case SC_CONTEXTHELP: if( (dwWndExStyle & WS_EX_CONTEXTHELP) != 0 ) bSysCmdEnabled = true; break; // case SC_NEXTWINDOW: // case SC_PREVWINDOW: // case SC_VSCROLL: // case SC_HSCROLL: // case SC_MOUSEMENU: // case SC_KEYMENU: // case SC_ARRANGE: // case SC_TASKLIST: // case SC_SCREENSAVE: //#if(WINVER >= 0x0400) // case SC_DEFAULT: // case SC_MONITORPOWER: // case SC_SEPARATOR: //#endif /* WINVER >= 0x0400 */ case SC_HOTKEY: default: continue; } // switch( nCmdID ) CExtCmdItem * pCmdItem = g_CmdManager->CmdGetPtr( g_CmdManager->ProfileNameFromWnd( m_hWndCmdReciever ), nCmdID ); ASSERT( pCmdItem != NULL ); pCmdItem->StateEnable( bSysCmdEnabled ); mi.Enable( bSysCmdEnabled ); } // for(; iter < m_items_all.end(); ++iter ) } // BLOCK: update system commands CWnd * pWndCmdReciever = CWnd::FromHandle( m_hWndCmdReciever ); ASSERT_VALID( pWndCmdReciever ); // pWndCmdReciever->ActivateTopParent(); // pWndCmdReciever->BringWindowToTop(); // pWndCmdReciever->SetFocus(); //_site._Hook( true ); // adjust own data bool bOldTopLevel = m_bTopLevel; bool bOldExpandAvailable = m_bExpandAvailable; _Init(); m_bTopLevel = bOldTopLevel; m_bExpandAvailable = bOldExpandAvailable; m_dwTrackFlags = dwTrackFlags; m_pCbPaintCombinedCookie = pCbPaintCombinedCookie; m_pCbPaintCombinedContent = pCbPaintCombinedContent; m_bCookieIsObject = bCookieIsObject; if( !m_bTopLevel ) { ASSERT( m_pWndParentMenu != NULL ); if( m_pWndParentMenu->m_bExpandWasPressed ) { if( m_bExpandAvailable ) { m_bExpandAvailable = false; m_bExpandWasPressed = true; _SyncItems(); } else m_bExpandWasPressed = true; } } // if( !m_bTopLevel ) else { if( bForceExpandRarelyUsed ) { if( m_bExpandAvailable ) { m_bExpandAvailable = false; m_bExpandWasPressed = true; _SyncItems(); } else m_bExpandWasPressed = true; } // if( bForceExpandRarelyUsed ) else _SyncItems(); } // else from if( !m_bTopLevel ) // adjust screen position m_ptTrack.x = x; m_ptTrack.y = y; if( m_ptTrack.x < 0 || m_ptTrack.y < 0 ) { if( ! ::GetCursorPos(&m_ptTrack) ) return FALSE; } if( lpRect != NULL ) { m_rcExcludeArea = *lpRect; m_bExcludeAreaSpec = true; } else { m_bExcludeAreaSpec = false; m_rcExcludeArea.left = m_ptTrack.x - __EXCLUDE_AREA_GAP_DX; m_rcExcludeArea.right = m_ptTrack.x + __EXCLUDE_AREA_GAP_DX; m_rcExcludeArea.top = m_ptTrack.y - __EXCLUDE_AREA_GAP_DY; m_rcExcludeArea.bottom = m_ptTrack.y + __EXCLUDE_AREA_GAP_DY; } // adjust combine with exclude area mode m_bCombineWithEA = false; if( m_bExcludeAreaSpec // && m_bTopLevel ) { switch( (dwTrackFlags&TPMX_COMBINE_MASK) ) { case TPMX_COMBINE_ANY_SUITABLE: m_bCombineWithEA = true; break; case TPMX_COMBINE_DEFAULT: m_bCombineWithEA = g_PaintManager-> IsMenuMustCombineExcludeArea(); break; } // switch( (dwTrackFlags&TPMX_COMBINE_MASK) ) } // if( m_bExcludeAreaSpec ... CSize _size = _CalcTrackSize(); bool bPointAdjusted = true; if( m_bExcludeAreaSpec ) { switch( (m_dwTrackFlags & TPMX_ALIGN_MASK) ) { case TPMX_LEFTALIGN: m_ptTrack.x = m_rcExcludeArea.right; m_ptTrack.y = m_rcExcludeArea.top; break; case TPMX_RIGHTALIGN: m_ptTrack.x = m_rcExcludeArea.left - _size.cx; m_ptTrack.y = m_rcExcludeArea.top; break; case TPMX_TOPALIGN: m_ptTrack.x = m_rcExcludeArea.left; m_ptTrack.y = m_rcExcludeArea.bottom; break; case TPMX_BOTTOMALIGN: m_ptTrack.x = m_rcExcludeArea.left; m_ptTrack.y = m_rcExcludeArea.top - _size.cy; break; default: bPointAdjusted = false; break; } // switch( (m_dwTrackFlags & TPMX_ALIGN_MASK) ) } // if( m_bExcludeAreaSpec ) if( !bPointAdjusted ) { if( (m_dwTrackFlags & TPMX_ALIGN_MASK) == TPMX_RIGHTALIGN ) m_ptTrack.x -= _size.cx; else { if( (m_dwTrackFlags & TPMX_ALIGN_MASK) == TPMX_CENTERALIGN ) m_ptTrack.x -= _size.cx/2; } if( (m_dwTrackFlags & TPMX_ALIGN_MASK) == TPMX_BOTTOMALIGN ) m_ptTrack.y -= _size.cy; else { if( (m_dwTrackFlags & TPMX_ALIGN_MASK) == TPMX_VCENTERALIGN ) m_ptTrack.y -= _size.cy/2; } } // if( !bPointAdjusted ) //#ifdef _DEBUG bool bCreateResult = //#endif // _DEBUG _CreateHelper( pWndCmdReciever ); //ASSERT( bCreateResult ); if( !bCreateResult ) { //_OnCancelMode(); return FALSE; } if( dwTrackFlags & TPMX_SELECT_ANY ) { int nItem = _GetNextItem(__NI_ANY); if( nItem >= 0 ) _ItemFocusSet( nItem, FALSE, FALSE ); } if( _FindCustomizeMode() ) m_AnimationType = __AT_NONE; else { m_AnimationType = g_DefAnimationType; if( CExtToolControlBar::g_bMenuTracking ) m_AnimationType = __AT_NONE; m_ePlaySoundOnAnimationFinished = CExtSoundPlayer::__ON_MENU_POPUP_DISPLAYED; _StartAnimation(); } // if( _FindCustomizeMode() ) if( m_AnimationType == __AT_NONE ) { m_AnimationType = __AT_CONTENT_DISPLAY; _StartAnimation(); ASSERT( m_AnimationType == __AT_CONTENT_DISPLAY ); } if( m_rgnWnd.GetSafeHandle() != NULL ) { ASSERT( m_bExcludeAreaSpec ); ASSERT( m_bCombineWithEA ); ASSERT( m_eCombineAlign != __CMBA_NONE ); CRgn rgnTmp; VERIFY( rgnTmp.CreateRectRgn(0,0,0,0) ); rgnTmp.CopyRgn( &m_rgnWnd ); ASSERT( rgnTmp.GetSafeHandle() != NULL ); VERIFY( SetWindowRgn( (HRGN)rgnTmp.Detach(), FALSE ) ); } // if( m_rgnWnd.GetSafeHandle() != NULL ) SetWindowPos( &CWnd::wndTopMost, 0, 0, 0, 0, SWP_NOACTIVATE |SWP_NOMOVE|SWP_NOSIZE |SWP_SHOWWINDOW //|SWP_NOREDRAW //|SWP_NOSENDCHANGING |SWP_NOZORDER //|SWP_NOOWNERZORDER //|SWP_NOCOPYBITS ); ASSERT( IsWindowVisible() ); if( !_FindCustomizeMode() ) _SetCapture(); #if (!defined __EXT_MFC_NO_CUSTOMIZE) else { CExtCustomizeSite * pSite = _FindCustomizeSite(); ASSERT( pSite != NULL ); pSite->RegisterCommandDropTarget( this, this ); } #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) return TRUE; } bool CExtPopupMenuWnd::_CreateHelper( CWnd * pWndCmdReciever ) { ASSERT_VALID( this ); bool bHasInplaceItems = false; int nCount = ItemGetCount(); for( int i = 0; i < nCount; i++ ) { MENUITEMDATA & mi = _GetItemRef( i ); if( !mi.IsInplaceEdit() ) continue; //ASSERT( mi.GetInplaceEditPtr() == NULL ); mi.ResetActiveInplaceEditPtr(); bHasInplaceItems = true; break; } // for( int i = 0; i < nCount; i++ ) if( bHasInplaceItems ) _SyncItems(); CRect wr = _CalcTrackRect(); if( wr.IsRectEmpty() ) return false; HCURSOR hCursor = ::LoadCursor(NULL, IDC_ARROW); ASSERT( hCursor != NULL ); CExtSafeString strMenuClassName = ::AfxRegisterWndClass( __POPUP_WNDCLASS_STYLES__, hCursor, (HBRUSH)(COLOR_BTNFACE + 1), NULL ); ASSERT( !strMenuClassName.IsEmpty() ); BOOL bCreateResult = __BaseClassOfCExtPopupBaseWnd::CreateEx( _FindCustomizeMode() ? 0 : WS_EX_TOPMOST, strMenuClassName, NULL, WS_POPUP, wr, pWndCmdReciever, 0 // IDC_STATIC ); if( !bCreateResult ) { ASSERT( FALSE ); return false; } _RecalcLayoutImpl(); if( !_FindHelpMode() ) ::SetCursor( hCursor ); //HWND hWndOwn = GetSafeHwnd(); // ASSERT( hWndOwn != NULL ); // ASSERT( ::IsWindow(hWndOwn) ); // PassMsgLoop( CExtPopupBaseWnd::g_bEnableOnIdleCalls ); // update all bottom // if( !::IsWindow(hWndOwn) ) // return false; if( bHasInplaceItems ) { visible_items_t v; _GetVisibleItems( NULL, v ); int nCount = v.GetSize(); for( i = 0; i < nCount; i++ ) { // MENUITEMDATA & mi = _GetItemRef( i ); VisibleItemDefinition_t & vi = v[ i ]; MENUITEMDATA & mi = _GetItemRef( vi.m_nIndex ); if( !mi.IsInplaceEdit() ) continue; //ASSERT( mi.GetInplaceEditPtr() == NULL ); mi.ResetActiveInplaceEditPtr(); // VisibleItemDefinition_t & vi = v[ i ]; CRect rc = mi.AdjustInplaceEditRect( vi.m_rcItem ); mi.CreateInplaceEdit( this, rc ); } // for( i = 0; i < nCount; i++ ) } // if( bHasInplaceItems ) return true; } BOOL CExtPopupMenuWnd::DestroyWindow() { ASSERT_VALID( this ); int nCount = ItemGetCount(); for( int i = 0; i < nCount; i++ ) { MENUITEMDATA & mi = _GetItemRef( i ); if( mi.IsInplaceEdit() ) { if( mi.GetInplaceEditPtr() != NULL ) { ASSERT_VALID( mi.GetInplaceEditPtr() ); ASSERT( mi.GetInplaceEditPtr()->GetSafeHwnd() != NULL && (::IsWindow(mi.GetInplaceEditPtr()->GetSafeHwnd())) ); mi.GetInplaceEditPtr()->DestroyWindow(); } // if( mi.GetInplaceEditPtr() != NULL ) mi.ResetActiveInplaceEditPtr(); } } // for( int i = 0; i < nCount; i++ ) if( !(::IsWindow(GetSafeHwnd())) ) return TRUE; #if (!defined __EXT_MFC_NO_CUSTOMIZE) if( _FindCustomizeMode() ) { CExtCustomizeSite * pSite = _FindCustomizeSite(); ASSERT( pSite != NULL ); pSite->UnRegisterCommandDropTarget( this ); } // if( _FindCustomizeMode() ) #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) return CExtPopupBaseWnd::DestroyWindow(); } void CExtPopupMenuWnd::_GetItemRect( int nIndex, RECT & rectItem ) { ASSERT_VALID( this ); CRect rcClient; _GetClientRect( &rcClient ); rcClient.left += m_nLeftAreaWidth; if( m_bScrollingAvailable ) { ASSERT( !m_rcScrollTop.IsRectEmpty() ); ASSERT( !m_rcScrollBottom.IsRectEmpty() ); if( nIndex == IDX_SCROLL_TOP ) { rectItem = m_rcScrollTop; return; } if( nIndex == IDX_SCROLL_BOTTOM ) { rectItem = m_rcScrollBottom; return; } } if( m_bExpandAvailable && nIndex == IDX_EXPAND ) { rectItem = m_rcExpandBtn; return; } int nCountOfItems = m_items_all.GetSize(); if( nCountOfItems == 0 ) { ((CRect *)(&rectItem))->SetRectEmpty(); return; } ASSERT( nIndex >= 0 && nIndex < nCountOfItems ); MENUITEMDATA & mi = m_items_all[nIndex]; if( !mi.IsDisplayed() ) { ::SetRectEmpty( &rectItem ); return; } int nMenuBorderSize = g_PaintManager->GetMenuBorderSize(); int y = m_nDyScrollOffset + nMenuBorderSize; CRect rcItem; rcItem.SetRectEmpty(); if( mi.IsToolButton() ) { rcItem.left = nMenuBorderSize + 1 + __EXT_MENU_TOOLBTN_GAP ; rcItem.right = mi.GetMeasuredWidth() ; } // if( mi.IsToolButton() ) else { rcItem.left = nMenuBorderSize + 1 ; rcItem.right = m_sizeFullItems.cx + nMenuBorderSize - 1 ; } // else from if( mi.IsToolButton() ) INT iter = 0; for( int i = 0; i < nIndex && iter != m_items_all.GetSize(); i++, iter++ ) { MENUITEMDATA & mi = m_items_all[ iter ]; if( !mi.IsDisplayed() ) continue; const RECT & rcBase = mi.GetBaseRect(); y += rcBase.bottom - rcBase.top; } ASSERT( iter != m_items_all.GetSize() ); rcItem.OffsetRect(0,y); mi = m_items_all[ iter ]; ASSERT( mi.IsDisplayed() ); const RECT & rcBase = mi.GetBaseRect(); rcItem.bottom = rcItem.top + rcBase.bottom - rcBase.top; // FIX for combined exclude area rcItem.OffsetRect( rcClient.TopLeft() ); rectItem = rcItem; } void CExtPopupMenuWnd::_GetVisibleItems( HDC hDcTest, // may be NULL visible_items_t & v ) { ASSERT_VALID( this ); v.RemoveAll(); INT iter = 0; for( int nIndex = 0; iter != m_items_all.GetSize(); iter++, nIndex++ ) { // find visible items MENUITEMDATA & mi = m_items_all[ iter ]; if( !mi.IsDisplayed() ) continue; CRect rcItem; _GetItemRect( nIndex, rcItem ); if( rcItem.IsRectEmpty() ) continue; if( hDcTest != NULL && (! ::RectVisible( hDcTest, &rcItem ) ) ) continue; VisibleItemDefinition_t vi; vi.m_nIndex = nIndex; vi.m_nHelperCmdID = mi.GetCmdID(); vi.m_rcItem = rcItem; if( mi.IsSeparator() ) { vi.m_bHelperIsSeparator = true; v.Add( vi ); continue; } if( mi.IsPopup() ) { vi.m_bHelperIsPopup = true; CExtCmdItem * pCmdItem = mi.GetCmd(); if( pCmdItem != NULL ) { vi.m_bRarelyUsed = ( (!_FindCustomizeMode()) && pCmdItem->StateIsRarelyUsed() ) ? true : false; } // if( pCmdItem != NULL ) else vi.m_bRarelyUsed = (!_FindCustomizeMode()) && mi.IsAllItemsRarelyUsed() && (!mi.IsForceDisplayed()) ; v.Add( vi ); continue; } if( mi.IsExtraMark() ) vi.m_bRarelyUsed = false; else { CExtCmdItem * pCmdItem = mi.GetCmd(); if( pCmdItem != NULL ) vi.m_bRarelyUsed = ( (!_FindCustomizeMode()) && pCmdItem->StateIsRarelyUsed() ) ? true : false; else vi.m_bRarelyUsed = false; } // else from if( mi.IsExtraMark() ) v.Add( vi ); } // find visible items INT vis_iter = 0; for( ; vis_iter < v.GetSize(); ++vis_iter ) { // setup prev/next rarely used flags VisibleItemDefinition_t & vi = v[ vis_iter ]; INT iter_prev = vis_iter; INT iter_next = vis_iter; if( vis_iter != 0 ) { --iter_prev; if( v[iter_prev].m_bRarelyUsed ) vi.m_bRarelyUsedPrev = true; } // if( vis_iter != v.begin() ) ++iter_next; if( iter_next != v.GetSize() ) { if( v[iter_next].m_bRarelyUsed ) vi.m_bRarelyUsedNext = true; } // if( iter_next != v.end() ) if( vi.m_bHelperIsSeparator ) { if( vi.m_bRarelyUsedPrev && vi.m_bRarelyUsedNext && (!_FindCustomizeMode()) ) { vi.m_bRarelyUsed = true; ASSERT( vis_iter != 0 ); v[iter_prev].m_bRarelyUsedNext = true; ASSERT( iter_next != 0 ); v[iter_next].m_bRarelyUsedPrev = true; } } } // setup prev/next rarely used flags } void CExtPopupMenuWnd::stat_paint_combined_menu_toolbtn( LPVOID pCookie, CDC & dc, const CWnd & refWndMenu, const CRect & rcExcludeArea, // in screen coords int eCombineAlign // CExtPopupMenuWnd::e_combine_align_t values ) { eCombineAlign; INT nIndex = (INT)pCookie; ASSERT( refWndMenu.GetSafeHwnd() != NULL ); ASSERT( ::IsWindow( refWndMenu.GetSafeHwnd() ) ); ASSERT( dc.GetSafeHdc() != NULL ); if( rcExcludeArea.IsRectEmpty() ) return; ASSERT_KINDOF( CExtPopupMenuWnd, (&refWndMenu) ); CExtPopupMenuWnd * pPopup = (CExtPopupMenuWnd *)(&refWndMenu); ASSERT_VALID( pPopup ); ASSERT( ! pPopup->m_bTopLevel ); CExtPopupMenuWnd * pPopup2 = pPopup->m_pWndParentMenu; ASSERT_VALID( pPopup2 ); ASSERT( 0 <= nIndex && nIndex < pPopup2->ItemGetCount() ); CExtPopupMenuWnd::MENUITEMDATA & mi = pPopup2->ItemGetInfo(nIndex); CRect rcItem; pPopup2->_GetItemRect( nIndex, rcItem ); CRect rcClientExcludeArea( rcExcludeArea ); pPopup->ScreenToClient( &rcClientExcludeArea ); rcItem.OffsetRect( - rcItem.TopLeft() ); rcItem.OffsetRect( rcClientExcludeArea.TopLeft() ); CRect rcTargetClient; pPopup->_GetClientRect( &rcTargetClient ); dc.ExcludeClipRect( &rcTargetClient ); CExtPopupMenuWnd::DRAWITEMDATA _DrawItemData( &dc, &rcItem, &mi, pPopup, ( pPopup->GetSite()->m_dwTrackFlags&TPMX_OWNERDRAW_FIXED ) ? true : false, mi.IsPopup(), false, // g_bMenuHighlightRarely && vi.m_bRarelyUsed, false, // g_bMenuHighlightRarely && vi.m_bRarelyUsedPrev, false // g_bMenuHighlightRarely && vi.m_bRarelyUsedNext ); bool bPainted = (_DrawItemData.m_bMenuOwnerDrawFixed) ? _DrawItemData.DoOwnerDrawPainting() : false ; if( !bPainted ) _DrawItemData.PaintDefault(); dc.SelectClipRgn( NULL ); } void CExtPopupMenuWnd::DRAWITEMDATA::PaintDefault( bool bForceNoIcon, // = false bool bForceNoText, // = false bool bForceNoCheck, // = false bool bForceEnabled, // = false bool bForceUnselected // = false ) { ASSERT( m_pDC != NULL ); ASSERT( m_pDC->GetSafeHdc() != NULL ); ASSERT( m_pRectItem != NULL ); ASSERT( m_pItemData != NULL ); ASSERT( m_pPopup != NULL ); #if (!defined __EXT_MFC_NO_CUSTOMIZE) CExtCustomizeSite * pSite = NULL; bool bCustomizeMode = false; #if (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD) bool bResizingNode = false; #endif // (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD) if( m_pPopup->_FindCustomizeMode() ) { pSite = m_pPopup->_FindCustomizeSite(); ASSERT( pSite != NULL ); bCustomizeMode = true; bForceNoCheck = bForceEnabled = true; // bForceUnselected = m_pItemData->IsPopup() ? false : true; #if (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD) CExtCustomizeCmdTreeNode * pNode = ((MENUITEMDATA *)m_pItemData)->GetCmdNode(); if( pNode != NULL ) { ASSERT_VALID( pNode ); if( pNode == pSite->GetResizingNode() ) bResizingNode = true; } #endif // (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD) } #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) if( m_pItemData->IsToolButton() ) { bool bSelDraw = bForceUnselected ? false : m_pItemData->IsSelected(); bool bTransparent = !m_pItemData->IsSelected(); if( bSelDraw && m_pItemData->IsPopup() ) { const CExtPopupMenuWnd * pChildPopup = m_pItemData->GetPopup(); if( pChildPopup->GetSafeHwnd() != NULL && ::IsWindow( pChildPopup->GetSafeHwnd() ) && (pChildPopup->GetStyle() & WS_VISIBLE) != NULL ) { bSelDraw = false; bTransparent = true; } } // if( bSelDraw && m_pItemData->IsPopup() ) CExtPaintManager::PAINTPUSHBUTTONDATA _ppbd( m_pPopup, true, *m_pRectItem, bForceNoText ? _T("") : m_pItemData->GetText(), ( bForceNoIcon ) ? NULL : ((MENUITEMDATA *)m_pItemData)->GetIconPtr(), true, bSelDraw, // hover bSelDraw, // pushed false, bForceEnabled || m_pItemData->IsEnabled() || m_pItemData->IsForceEnabled(), m_pItemData->IsSelected(), // border false, false, CExtPaintManager::__ALIGN_VERT, NULL, m_pItemData->IsPopup() ? true : false, 0, bTransparent // transparent ); g_PaintManager->PaintPushButton( *m_pDC, _ppbd ); } // if( m_pItemData->IsToolButton() ) else { CExtCmdIcon * pIcon = ( bForceNoIcon ) ? NULL : ((MENUITEMDATA *)m_pItemData)->GetIconPtr(); if( pIcon != NULL && pIcon->IsEmpty() ) pIcon = NULL; CExtCmdIcon _iconLarge; if( g_bMenuLargeIcons && pIcon != NULL ) { CSize _sizeIcon = pIcon->GetSize(); _sizeIcon.cx *= 2; _sizeIcon.cy *= 2; if( _iconLarge.CreateScaledCopy( *pIcon, _sizeIcon ) ) pIcon = &_iconLarge; #ifdef _DEBUG else { ASSERT( FALSE ); } #endif // _DEBUG } // if( g_bMenuLargeIcons && pIcon != NULL ) CExtPaintManager::PAINTMENUITEMDATA _pmid( m_pPopup, CRect( *m_pRectItem ), m_pItemData->GetIconAreaWidth(), bForceNoText ? _T("") : m_pItemData->GetText(), bForceNoText ? _T("") : m_pItemData->GetAccelText(), pIcon, m_bPopupItem, bForceUnselected ? false : m_pItemData->IsSelected(), bForceNoCheck ? false : m_pItemData->GetCheck(), bForceNoCheck ? false : m_pItemData->GetRadio(), m_pItemData->IsIndeterminated(), bForceEnabled || m_pItemData->IsEnabled() || m_pItemData->IsForceEnabled(), m_bRarelyUsed, m_bRarelyUsedPrevious, m_bRarelyUsedNext, m_pItemData->GetCmdID() ); _pmid.m_bForceNoLeftGradient = m_pItemData->IsForceNoLeftGradient(); if( ((MENUITEMDATA *)m_pItemData)->IsInplaceEdit() ) { _pmid.m_rcInPlaceWnd = m_pItemData->AdjustInplaceEditRect( *m_pRectItem ); _pmid.m_strInPlaceText = m_pItemData->GetInplaceEditText(); } // if( ((MENUITEMDATA *)m_pItemData)->IsInplaceEdit() ) if( m_pItemData->IsExtraMark() ) { _pmid.m_bXtraMark = true; _pmid.m_bXtraChecked = m_pItemData->IsExtraChecked(); } // if( m_pItemData->IsExtraMark() ) ASSERT( !_pmid.m_bHelperPopupDropped ); if( m_pItemData->IsPopup() && m_pItemData->GetPopup()->GetSafeHwnd() != NULL && m_pItemData->GetPopup()->IsWindowVisible() ) _pmid.m_bHelperPopupDropped = true; #if (!defined __EXT_MFC_NO_CUSTOMIZE) #if (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD) if( bResizingNode ) _pmid.m_bSelected = true; #endif // (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD) #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) g_PaintManager->PaintMenuItem( *m_pDC, _pmid ); } // else from if( m_pItemData->IsToolButton() ) #if (!defined __EXT_MFC_NO_CUSTOMIZE) if( m_pPopup->m_nHelperDropIndexBefore >= 0 ) { int nCount = m_pPopup->ItemGetCount(); ASSERT( m_pPopup->m_nHelperDropIndexBefore <= nCount ); int nAlignAt = 0; int nItemIndex = m_pItemData->GetIndex(); if( nItemIndex == m_pPopup->m_nHelperDropIndexBefore ) nAlignAt = -1; else if( nItemIndex == ( nCount - 1 ) && m_pPopup->m_nHelperDropIndexBefore == nCount ) nAlignAt = 1; else if( ( nItemIndex + 1 ) == m_pPopup->m_nHelperDropIndexBefore && m_pPopup->_GetItemRef( nItemIndex + 1 ).IsSeparator() ) { nItemIndex; nAlignAt = 1; } if( nAlignAt != 0 ) { // if paint drop divider CSize _sizeDDM = g_PaintManager->GetDropDividerMerics(); CRect rcItem; ASSERT( !m_pPopup->_GetItemRef(nItemIndex).IsSeparator() ); m_pPopup->_GetItemRect( nItemIndex, rcItem ); int nY = ( nAlignAt > 0 ) ? rcItem.bottom - _sizeDDM.cy/2 : rcItem.top + _sizeDDM.cy/2 ; rcItem.top = rcItem.bottom = nY; g_PaintManager->PaintDropDivider( *m_pDC, rcItem, true, false ); } // if( nAlignAt != 0 ) } // if( m_pPopup->m_nHelperDropIndexBefore >= 0 ) if( bCustomizeMode ) { ASSERT( pSite != NULL ); if( ( pSite != NULL && ( pSite->CustomizedNodeGet() != NULL && pSite->CustomizedNodeGet() == ((MENUITEMDATA*)m_pItemData)->GetCmdNode() ) ) || ( m_pPopup->m_pDragSrcNode != NULL && ((MENUITEMDATA*)m_pItemData)->GetCmdNode() == m_pPopup->m_pDragSrcNode ) #if (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD) || bResizingNode #endif // (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD) ) { CRect rcItem = m_pRectItem; g_PaintManager->PaintDragSourceRect( *m_pDC, rcItem ); } } // if( bCustomizeMode ) #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) } bool CExtPopupMenuWnd::DRAWITEMDATA::DoOwnerDrawPainting() { ASSERT( m_pDC != NULL ); ASSERT( m_pDC->GetSafeHdc() != NULL ); ASSERT( m_pRectItem != NULL ); ASSERT( m_pItemData != NULL ); ASSERT( m_pPopup != NULL ); HWND hWndNotify = m_pPopup->m_hWndCmdReciever; ASSERT( hWndNotify != NULL ); ASSERT( ::IsWindow(hWndNotify) ); LRESULT lResult = ::SendMessage( hWndNotify, CExtPopupMenuWnd::g_nMsgPopupDrawItem, 0, LPARAM( *this ) ); return lResult ? true : false; } bool CExtPopupMenuWnd::DRAWLEFTAREADATA::DoOwnerDrawPainting() { ASSERT( m_pDC != NULL ); ASSERT( m_pDC->GetSafeHdc() != NULL ); ASSERT( m_pRectLeftArea != NULL ); ASSERT( m_pPopup != NULL ); HWND hWndNotify = m_pPopup->m_hWndCmdReciever; ASSERT( hWndNotify != NULL ); ASSERT( ::IsWindow(hWndNotify) ); LRESULT lResult = ::SendMessage( hWndNotify, CExtPopupMenuWnd::g_nMsgPopupDrawLeftArea, 0, LPARAM( *this ) ); return lResult ? true : false; } void CExtPopupMenuWnd::_DoPaint( CDC & dcPaint, bool bUseBackBuffer // = true ) { ASSERT_VALID( this ); ASSERT_VALID( (&dcPaint) ); ASSERT( dcPaint.GetSafeHdc() != NULL ); if( m_hWnd != NULL ) { ASSERT( ::IsWindow(m_hWnd) ); CExtPaintManager::stat_ExcludeChildAreas( dcPaint.GetSafeHdc(), m_hWnd ); } // if( m_hWnd != NULL ) ASSERT( m_hWndCmdReciever != NULL ); ASSERT( ::IsWindow(m_hWndCmdReciever) ); CRect rcRealClient; GetClientRect( &rcRealClient ); CRect rcClient; _GetClientRect( &rcClient ); CPalette * pOldPalette = NULL, * pOldPalette2 = NULL; if( dcPaint.GetDeviceCaps(RASTERCAPS) & RC_PALETTE ) { pOldPalette = dcPaint.SelectPalette( &g_PaintManager->m_PaletteWide, FALSE ); dcPaint.RealizePalette(); } //bUseBackBuffer = false; //bUseBackBuffer = true; //dcPaint.SetViewportOrg( CPoint(0,0) ); CExtMemoryDC mdc; if( bUseBackBuffer ) { mdc.__InitMemoryDC( &dcPaint, &rcClient // &rcRealClient ); //mdc.SetViewportOrg( CPoint(0,0) ); if( pOldPalette != NULL ) { pOldPalette2 = mdc.SelectPalette( &g_PaintManager->m_PaletteWide, FALSE ); mdc.RealizePalette(); } } CDC & dcDummyRef = mdc; CDC & dc = bUseBackBuffer ? dcDummyRef : dcPaint; CFont * pOldFont = (CFont *) dc.SelectObject( &g_PaintManager->m_FontNormal ); dc.FillSolidRect( &rcClient, g_PaintManager->GetMenuFrameFillColor() ); g_PaintManager->PaintMenuBorder( dc, rcClient, this ); CRect rcExpand; if( m_bExpandAvailable ) { _GetItemRect( IDX_EXPAND, rcExpand ); CRect rcExcludePart( rcExpand ); rcExcludePart.InflateRect( 0, 1 ); rcExcludePart.left = rcRealClient.left; rcExcludePart.right = rcRealClient.right; dc.ExcludeClipRect( rcExcludePart ); } CRect rcScrollTop,rcScrollBottom; int nMaxScrollPos = 0; if( m_bScrollingAvailable ) { if( m_nDyScrollOffset != 0 ) { _GetItemRect( IDX_SCROLL_TOP, rcScrollTop ); CRect rcExcludePart( rcScrollTop ); rcExcludePart.InflateRect( 0, 1 ); rcExcludePart.left = rcRealClient.left; rcExcludePart.right = rcRealClient.right; dc.ExcludeClipRect( rcExcludePart ); } nMaxScrollPos = _GetMaxScrollPos(); if( m_nDyScrollOffset != nMaxScrollPos ) { _GetItemRect( IDX_SCROLL_BOTTOM, rcScrollBottom ); CRect rcExcludePart( rcScrollBottom ); rcExcludePart.InflateRect( 0, 1 ); rcExcludePart.left = rcRealClient.left; rcExcludePart.right = rcRealClient.right; dc.ExcludeClipRect( rcExcludePart ); } } int nMenuBorderSize = g_PaintManager->GetMenuBorderSize(); int nMenuShadowSize = _GetPopupShadowSize(); // if( rcClient.left >= rcRealClient.left ) // { // CRect rcExcludePart(rcRealClient); // rcExcludePart.right = // rcClient.left + nMenuBorderSize; // dc.ExcludeClipRect( rcExcludePart ); // } // if( rcClient.right <= rcRealClient.right ) // { // CRect rcExcludePart(rcRealClient); // rcExcludePart.left = // rcClient.right - nMenuBorderSize; // dc.ExcludeClipRect( rcExcludePart ); // } if( rcClient.top >= rcRealClient.top ) { CRect rcExcludePart(rcRealClient); rcExcludePart.bottom = rcClient.top + nMenuBorderSize; dc.ExcludeClipRect( rcExcludePart ); } if( rcClient.bottom <= rcRealClient.bottom ) { CRect rcExcludePart(rcRealClient); rcExcludePart.top = rcClient.bottom - nMenuBorderSize; dc.ExcludeClipRect( rcExcludePart ); } visible_items_t v; _GetVisibleItems( dc.GetSafeHdc(), v ); INT vis_iter = 0; bool bPrevToolButton = false; for( ; vis_iter < v.GetSize(); ++vis_iter ) { // paint visible items VisibleItemDefinition_t & vi = v[ vis_iter ]; ASSERT( vi.m_nIndex >= 0 && vi.m_nIndex < m_items_all.GetSize() ); ASSERT( !vi.m_rcItem.IsRectEmpty() ); ASSERT( dc.RectVisible(&vi.m_rcItem) ); MENUITEMDATA & mi = m_items_all[vi.m_nIndex]; ASSERT( mi.IsDisplayed() ); ASSERT( mi.GetCmdID() == vi.m_nHelperCmdID ); if( vi.m_bHelperIsSeparator ) { ASSERT( mi.IsSeparator() ); if( bPrevToolButton ) { CRect rcSep( vi.m_rcItem ); rcSep.top += rcSep.Height()/2 - 1; rcSep.bottom = rcSep.top + 2; g_PaintManager->PaintSeparator( dc, rcSep, false, false, this ); } // if( bPrevToolButton ) else g_PaintManager->PaintMenuSeparator( dc, vi.m_rcItem, mi.GetIconAreaWidth(), g_bMenuHighlightRarely && vi.m_bRarelyUsed, this ); bPrevToolButton = false; continue; } ASSERT( !mi.IsSeparator() ); ASSERT( mi.IsPopup() == vi.m_bHelperIsPopup ); DRAWITEMDATA _DrawItemData( &dc, &vi.m_rcItem, &mi, this, ( (! _FindCustomizeMode() ) && ( GetSite()->m_dwTrackFlags&TPMX_OWNERDRAW_FIXED ) != 0 // fix 2.23 ( == replaced with != ) ) ? true : false, vi.m_bHelperIsPopup, g_bMenuHighlightRarely && vi.m_bRarelyUsed, g_bMenuHighlightRarely && vi.m_bRarelyUsedPrev, g_bMenuHighlightRarely && vi.m_bRarelyUsedNext ); bool bPainted = (_DrawItemData.m_bMenuOwnerDrawFixed) ? _DrawItemData.DoOwnerDrawPainting() : false ; if( !bPainted ) _DrawItemData.PaintDefault(); bPrevToolButton = mi.IsToolButton(); } // paint visible items CPoint point( 0, 0 ); ::GetCursorPos( &point ); ScreenToClient( &point ); dc.SelectClipRgn( NULL ); if( m_bExpandAvailable ) { bool bHover = (rcExpand.PtInRect(point))? true : false; bool bPushed = bHover; g_PaintManager->PaintMenuExpandButton( dc, rcExpand, bHover, bPushed, this ); } // if( m_bExpandAvailable ) if( m_bScrollingAvailable ) { if( m_nDyScrollOffset != 0 ) { bool bHover = (rcScrollTop.PtInRect(point))? true : false; bool bPushed = ( m_nScrollingDirection > 0 ) ? true : false; bPushed = bPushed || bHover; CExtPaintManager::PAINTPUSHBUTTONDATA _ppbd( this, true, rcScrollTop, _T("t"), // up arrow NULL, true,false/*bHover*/,bPushed,false, true,true,false,false, CExtPaintManager::__ALIGN_HORIZ_CENTER | CExtPaintManager::__ALIGN_VERT, (HFONT)g_PaintManager->m_FontMarlett.GetSafeHandle() ); g_PaintManager->PaintPushButton( dc, _ppbd ); } if( m_nDyScrollOffset != nMaxScrollPos ) { bool bHover = (rcScrollBottom.PtInRect(point))? true : false; bool bPushed = ( m_nScrollingDirection < 0 ) ? true : false; bPushed = bPushed || bHover; CExtPaintManager::PAINTPUSHBUTTONDATA _ppbd( this, true, rcScrollBottom, _T("u"), // down arrow NULL, true,false/*bHover*/,bPushed,false, true,true,false,false, CExtPaintManager::__ALIGN_HORIZ_CENTER | CExtPaintManager::__ALIGN_VERT, (HFONT)g_PaintManager->m_FontMarlett.GetSafeHandle() ); g_PaintManager->PaintPushButton( dc, _ppbd ); } } // if( m_bScrollingAvailable ) if( m_nLeftAreaWidth > 0 ) { CRect rcLeftArea( rcClient ); rcLeftArea.right = rcLeftArea.left + m_nLeftAreaWidth; rcLeftArea.OffsetRect( nMenuBorderSize, 0 ); rcLeftArea.DeflateRect( 0, nMenuBorderSize ); DRAWLEFTAREADATA _DrawLeftAreaData( &dc, &rcLeftArea, this ); _DrawLeftAreaData.DoOwnerDrawPainting(); } if( m_bCombineWithEA ) { ASSERT( m_eCombineAlign != __CMBA_NONE ); dc.SelectClipRgn(NULL); CRect rcExcludeClient( m_rcExcludeArea ); ScreenToClient( &rcExcludeClient ); g_PaintManager->PaintMenuCombinedArea( dc, rcExcludeClient, rcClient, m_eCombineAlign, this ); if( m_pCbPaintCombinedContent != NULL ) m_pCbPaintCombinedContent( m_pCbPaintCombinedCookie, dc, *this, m_rcExcludeArea, m_eCombineAlign ); } // if( m_bCombineWithEA ) dc.SelectObject( pOldFont ); if( bUseBackBuffer ) { ASSERT( mdc.GetSafeHdc() != NULL ); if( pOldPalette2 != NULL ) mdc.SelectPalette( pOldPalette2, FALSE ); mdc.__Flush(); } if( _IsPopupWithShadows() && m_bAnimFinished && nMenuShadowSize > 0 ) { // if we need to paint shadow for client area (and combined exclude area) dcPaint.SelectClipRgn(NULL); CRect rcExcludeClient( 0,0,0,0 ), rcExcludeScreen( 0,0,0,0 ), rcBaseScreen( 0,0,0,0 ); if( m_bCombineWithEA ) { if( _IsPopupWithShadows() && m_bAnimFinished && nMenuShadowSize > 0 && m_bTopLevel ) { // if we need to paint shadow for combined exclude area rcExcludeScreen = m_rcExcludeArea; rcExcludeClient = rcExcludeScreen; ScreenToClient( &rcExcludeClient ); dcPaint.ExcludeClipRect( &rcClient ); rcBaseScreen = rcClient; ClientToScreen( &rcBaseScreen ); VERIFY( m_ShadowCMBA.Paint( dcPaint, rcExcludeClient, rcExcludeScreen, rcBaseScreen, nMenuShadowSize ) ); dcPaint.SelectClipRgn(NULL); } // if we need to paint shadow for combined exclude area CRect rcExcludePart( m_rcExcludeArea ); ScreenToClient( &rcExcludePart ); dcPaint.ExcludeClipRect( &rcExcludePart ); } // if( m_bCombineWithEA ) VERIFY( m_ShadowMain.Paint( dcPaint, rcClient, rcBaseScreen, rcExcludeScreen, nMenuShadowSize ) ); } // if we need to paint shadow for client area (and combined exclude area) if( pOldPalette != NULL ) dcPaint.SelectPalette( pOldPalette, FALSE ); } #if _MFC_VER < 0x700 void CExtPopupMenuWnd::OnActivateApp(BOOL bActive, HTASK hTask) #else void CExtPopupMenuWnd::OnActivateApp(BOOL bActive, DWORD hTask) #endif { ASSERT_VALID( this ); bActive; hTask; _OnCancelMode(); } bool CExtPopupMenuWnd::_StartScrolling(int nButtonIndex) { ASSERT_VALID( this ); if( GetSafeHwnd() == NULL ) return FALSE; if( (nButtonIndex == IDX_SCROLL_TOP || nButtonIndex == IDX_SCROLL_BOTTOM) // && m_nCurIndex != nButtonIndex ) { ASSERT( m_bScrollingAvailable ); _ItemFocusDelay(); _ItemFocusCancel( FALSE ); m_nCurIndex = nButtonIndex; Invalidate( FALSE ); SetTimer( ID_TIMER_SCROLLING, ID_PERIOD_SCROLLING, NULL ); if( !_FindCustomizeMode() ) _SetCapture(); return true; } return false; } bool CExtPopupMenuWnd::_PtInWndArea( CPoint ptClient ) { if( GetSafeHwnd() == NULL ) return false; ClientToScreen( &ptClient ); HWND hWndFromPoint = ::WindowFromPoint(ptClient); if( hWndFromPoint == NULL ) return false; if( hWndFromPoint == m_hWnd ) return true; return false; } bool CExtPopupMenuWnd::_OnMouseClick( UINT nFlags, CPoint point, bool & bNoEat ) { ASSERT_VALID( this ); if( GetSafeHwnd() == NULL ) return false; if( !m_bAnimFinished ) return true; CExtPopupMenuSite & _site = GetSite(); if( _site.IsShutdownMode() || _site.IsEmpty() || _site.GetAnimated() != NULL ) return true; CPoint ptScreenClick( point ); ClientToScreen( &ptScreenClick ); HWND hWndFromPoint = ::WindowFromPoint( ptScreenClick ); if( hWndFromPoint != NULL && (::GetWindowLong(hWndFromPoint,GWL_STYLE)&WS_CHILD) != 0 && ::GetParent(hWndFromPoint) == m_hWnd ) { CWnd * pWnd = CWnd::FromHandlePermanent( hWndFromPoint ); if( pWnd != NULL ) { int nCount = ItemGetCount(); for( int i = 0; i < nCount; i++ ) { MENUITEMDATA & mi = _GetItemRef( i ); if( !mi.IsInplaceEdit() ) continue; if( ((LPVOID)mi.GetInplaceEditPtr()) != ((LPVOID)pWnd) ) continue; if( m_nCurIndex == i ) break; _ItemFocusSet( i, FALSE, TRUE, TRUE ); break; } // for( int i = 0; i < nCount; i++ ) } // if( pWnd != NULL ) bNoEat = true; return false; } bool bLButtonUpCall = (nFlags==WM_LBUTTONUP || nFlags==WM_NCLBUTTONUP) ? true : false; /* CRect rectWindow; GetWindowRect( &rectWindow ); ScreenToClient( &rectWindow ); if( !rectWindow.PtInRect(point) ) */ if( bLButtonUpCall && (!_PtInWndArea(point)) ) { if( m_wndToolTip.GetSafeHwnd() != NULL ) { CPoint ptScreen( point ); ClientToScreen( &ptScreen ); if( m_wndToolTip.GetSafeHwnd() == ::WindowFromPoint(ptScreen) ) return true; // eat! } if( m_pWndParentMenu != NULL && m_pWndParentMenu->GetSafeHwnd() != NULL ) { ASSERT_VALID( m_pWndParentMenu ); ClientToScreen( &point ); m_pWndParentMenu->ScreenToClient( &point ); HWND hWndOwn = GetSafeHwnd(); ASSERT( hWndOwn != NULL ); ASSERT( ::IsWindow(hWndOwn) ); CExtPopupMenuWnd * pWndParentMenu = m_pWndParentMenu; if( pWndParentMenu->_OnMouseClick( nFlags, point, bNoEat ) ) { if( bNoEat ) return false; if( ::IsWindow(hWndOwn) ) _OnCancelMode(); return true; } return false; } // fixed in v. 2.20 if( nFlags == WM_RBUTTONUP || nFlags == WM_LBUTTONUP ) { return true; } _OnCancelMode(); return false; } // if( bLButtonUpCall && (!_PtInWndArea(point)) ) bool bInplaceControlArea = false, bInplaceDropDownArea = false; int nHitTest = _HitTest( point, &bInplaceControlArea, &bInplaceDropDownArea ); if( bLButtonUpCall ) { if( _StartScrolling(nHitTest) ) return true; } if( nHitTest < 0 ) { if( bLButtonUpCall ) { if( (nHitTest == IDX_SCROLL_TOP || nHitTest == IDX_SCROLL_BOTTOM) //&& m_nCurIndex != nHitTest ) { return true; } if( nHitTest == IDX_EXPAND ) { if( (!m_bExpandWasPressed) && m_bExpandAvailable ) _DoExpand(); return true; } // fixed in v. 2.20 if( nFlags != WM_RBUTTONUP && nFlags != WM_LBUTTONUP ) { _OnCancelMode(); return true; } } // if( bLButtonUpCall ) if( m_eCombineAlign != __CMBA_NONE && m_bTopLevel && (!bLButtonUpCall) ) { CRect rcExcludeAreaTest( m_rcExcludeArea ); ScreenToClient( &rcExcludeAreaTest ); if( rcExcludeAreaTest.PtInRect( point ) ) { _OnCancelMode(); return true; } // if( rcExcludeAreaTest.PtInRect( point ) ) } // if( m_eCombineAlign != __CMBA_NONE ... return false; } ASSERT( nHitTest < m_items_all.GetSize() ); if( !bLButtonUpCall ) return true; MENUITEMDATA & mi = _GetItemRef(nHitTest); if( (!mi.IsEnabled()) || mi.IsSeparator() ) //return false; return true; if( mi.IsInplaceEdit() && mi.IsPopup() && (! mi.IsAllowInplaceEditActivation() ) ) { bInplaceControlArea = false; bInplaceDropDownArea = true; } if( mi.IsInplaceEdit() && (!mi.IsPopup()) && (! bInplaceDropDownArea ) && (! _FindHelpMode() ) ) { _SetCapture(); _ItemFocusSet( nHitTest, FALSE, TRUE ); CWnd * pWndInplace = mi.GetInplaceEditPtr(); if( pWndInplace != NULL ) { ASSERT_VALID( pWndInplace ); ASSERT( pWndInplace->GetSafeHwnd() != NULL && (::IsWindow(pWndInplace->GetSafeHwnd())) ); if( mi.IsAllowInplaceEditActivation() ) { if( (pWndInplace->GetStyle() & WS_VISIBLE) == 0 ) { CRect rcInplaceEdit; _GetItemRect( nHitTest, rcInplaceEdit ); rcInplaceEdit = mi.AdjustInplaceEditRect( rcInplaceEdit ); pWndInplace->SetWindowPos( NULL, rcInplaceEdit.left, rcInplaceEdit.top, rcInplaceEdit.Width(), rcInplaceEdit.Height(), SWP_NOZORDER|SWP_NOOWNERZORDER |SWP_NOACTIVATE|SWP_SHOWWINDOW ); } // if( (pWndInplace->GetStyle() & WS_VISIBLE) == 0 ) pWndInplace->SetFocus(); } // if( mi.IsAllowInplaceEditActivation() ) } // if( pWndInplace != NULL ) return true; } // if( mi.IsInplaceEdit() ... if( mi.IsPopup() ) { if( mi.GetPopup()->GetSafeHwnd() != NULL ) return false; #if (!defined __EXT_MFC_NO_CUSTOMIZE) if( mi.IsInplaceEdit() && _FindHelpMode() ) { CExtCustomizeCmdTreeNode * pNode = mi.GetCmdNode(); if( pNode != NULL ) _EndSequence( pNode->GetCmdID( false ), mi.GetCmdReciever() ); } // if( mi.IsInplaceEdit() && _FindHelpMode() ) #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) if( mi.IsInplaceEdit() && bInplaceDropDownArea ) _ItemFocusCancel( FALSE ); if( m_nDelayedFocusItemIndex < 0 ) // fix 2.23 condition for care about current animation status _ItemFocusSet( nHitTest, TRUE, TRUE ); return true; } // if( mi.IsPopup() ) if( mi.IsExtraMark() ) { ASSERT( mi.GetExtraMarkCallback() != NULL ); mi.GetExtraMarkCallback()( this, &mi ); CClientDC dc( this ); _DoPaint( dc ); } // if( mi.IsExtraMark() ) else if( mi.IsExecutableCmdID() ) { if( !( mi.GetCmdDeliverCb() != NULL && mi.GetCmdDeliverCb()( this, &mi ) ) ) _EndSequence( mi.GetCmdID(), mi.GetCmdReciever() ); } // else if( mi.IsExecutableCmdID() ) else _OnCancelMode(); // return false; return true; } void CExtPopupMenuWnd::_EndSequence( UINT nCmdID, // = 0 HWND hWndDeliver // = NULL ) { ASSERT_VALID( this ); #ifdef _DEBUG if( hWndDeliver != NULL ) { ASSERT( ::IsWindow(hWndDeliver) ); } #endif // _DEBUG ASSERT( m_hWndCmdReciever != NULL ); ASSERT( ::IsWindow(m_hWndCmdReciever) ); CExtPopupMenuSite & _site = GetSite(); UINT * lpnResultCmdID = _site.GetTargetCmdIdPtr(); if( lpnResultCmdID != NULL ) *lpnResultCmdID = nCmdID; CExtCmdItem * pCmdItem = NULL; if( nCmdID > 0 && ((m_dwTrackFlags&TPMX_NO_WM_COMMAND)==0) ) { pCmdItem = g_CmdManager->CmdGetPtr( g_CmdManager->ProfileNameFromWnd( m_hWndCmdReciever ), nCmdID ); ASSERT( pCmdItem != NULL ); } // if( nCmdID > 0 && ((m_dwTrackFlags&TPMX_NO_WM_COMMAND)==0) ) CExtPopupMenuWnd * pTopPopup = _site.GetInstance(); ASSERT_VALID( pTopPopup ); HWND hWndTopPopup = pTopPopup->GetSafeHwnd(); ASSERT( hWndTopPopup != NULL && ::IsWindow( hWndTopPopup ) ); if( hWndDeliver == NULL ) hWndDeliver = m_hWndCmdReciever; CWnd * pTopLevelParent = GetTopLevelParent(); HWND hWndTopLevelParent = pTopLevelParent->GetSafeHwnd(); CRect rcBkUpdate( 0, 0, 0, 0 ); // hide all sequence CExtPopupMenuWnd * pPopup = this; for( ; pPopup != NULL; pPopup = pPopup->m_pWndParentMenu ) { ASSERT_VALID( pPopup ); ASSERT( pPopup->GetSafeHwnd() != NULL ); ASSERT( ::IsWindow( pPopup->GetSafeHwnd() ) ); CRect rcPopup; pPopup->GetWindowRect( &rcPopup ); if( rcBkUpdate.IsRectEmpty() ) rcBkUpdate = rcPopup; else { CRect rcPrev( rcBkUpdate ); rcBkUpdate.UnionRect( &rcPrev, &rcPopup ); } if( pPopup->m_wndToolTip.GetSafeHwnd() != NULL && ::IsWindow( pPopup->m_wndToolTip.GetSafeHwnd() ) && pPopup->m_wndToolTip.IsWindowVisible() ) { CRect rcToolTip; pPopup->m_wndToolTip.GetWindowRect( &rcToolTip ); CRect rcPrev( rcBkUpdate ); rcBkUpdate.UnionRect( &rcPrev, &rcToolTip ); } pPopup->ShowWindow( SW_HIDE ); } // for( ; pPopup != NULL; pPopup = pPopup->m_pWndParentMenu ) // allow bottom windows repaint if( !rcBkUpdate.IsRectEmpty() && hWndTopLevelParent != NULL && ::IsWindow(hWndTopLevelParent) ) { ::ScreenToClient( hWndTopLevelParent, (LPPOINT)&rcBkUpdate); ::ScreenToClient( hWndTopLevelParent, ((LPPOINT)&rcBkUpdate)+1 ); #if (WINVER >= 0x0500) ASSERT( WS_EX_LAYOUTRTL == 0x00400000L ); #endif if( ( (DWORD) ::GetWindowLong( hWndTopLevelParent, GWL_EXSTYLE ) ) & 0x00400000L // WS_EX_LAYOUTRTL under Win 5x ) { //CRect::SwapLeftRight( &rcBkUpdate ); LONG temp = rcBkUpdate.left; rcBkUpdate.left = rcBkUpdate.right; rcBkUpdate.right = temp; } ::RedrawWindow( hWndTopLevelParent, &rcBkUpdate, NULL, RDW_INVALIDATE|RDW_ERASE |RDW_UPDATENOW|RDW_ERASENOW |RDW_VALIDATE |RDW_FRAME|RDW_ALLCHILDREN ); } // top popup (and all children) finally must be closed if( ::IsWindow( hWndTopPopup ) ) ::PostMessage( hWndTopPopup, WM_CLOSE, 0, 0 ); if( CExtToolControlBar::g_bMenuTracking ) CExtToolControlBar::_CloseTrackingMenus(); //CExtToolControlBar * pToolBar = CExtToolControlBar::_GetMenuTrackingBar(); // if( pToolBar != NULL ) // pToolBar->PostMessage( WM_CANCELMODE ); if( pCmdItem != NULL && ::IsWindow(hWndDeliver) && (! _FindCustomizeMode() ) ) { // if command target still exists -> deliver command to it VERIFY( pCmdItem->Deliver(hWndDeliver) ); g_SoundPlayer->PlaySound( CExtSoundPlayer::__ON_MENU_CMD_CLICKED ); } // if( pCmdItem != NULL && ... } void CExtPopupMenuWnd::OnMouseMove(UINT nFlags, CPoint point) { nFlags; point; #if (!defined __EXT_MFC_NO_CUSTOMIZE) if( (!_FindCustomizeMode()) ) return; int nIndex = _HitTest( point ); if( nIndex >= 0 ) return; if( nIndex == IDX_SCROLL_TOP || nIndex == IDX_SCROLL_BOTTOM ) _StartScrolling( nIndex ); #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) } void CExtPopupMenuWnd::OnLButtonDown(UINT nFlags, CPoint point) { nFlags; point; #if (!defined __EXT_MFC_NO_CUSTOMIZE) if( (!_FindCustomizeMode()) ) return; int nIndex = _HitTest( point ); if( nIndex < 0 ) return; ASSERT( nIndex < ItemGetCount() ); MENUITEMDATA & mi = _GetItemRef( nIndex ); if( mi.IsSeparator() ) return; CExtCustomizeSite * pSite = _FindCustomizeSite(); ASSERT( pSite != NULL ); CExtCustomizeCmdTreeNode * pClickedCmdNode = mi.GetCmdNode(); ASSERT_VALID( pClickedCmdNode ); #if (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD) if( mi.IsSelected() && (pClickedCmdNode->GetFlags() & __ECTN_TBB_RESIZABLE) != 0 ) { // if button can be resized int nDdWidth = g_PaintManager->GetDropDividerMerics().cx / 2; if( nDdWidth < 2 ) nDdWidth = 2; CRect rcItem( 0, 0, 0, 0 ); _GetItemRect( nIndex, rcItem ); CRect rcH( rcItem ); rcH.right = rcH.left + nDdWidth; int nInitialResizingStateH = 0; if( rcH.PtInRect(point) ) nInitialResizingStateH = -1; else { rcH = rcItem; rcH.left = rcH.right - nDdWidth; if( rcH.PtInRect(point) ) nInitialResizingStateH = 1; } // else from if( rcH.PtInRect(point) ) if( nInitialResizingStateH != 0 ) { int nWidthMin = 0, nWidthMax = 0; pSite->OnGetCmdItemMinMaxSizeH( NULL, pClickedCmdNode, &nWidthMin, &nWidthMax ); CRect rcInplaceEdit = mi.AdjustInplaceEditRect( rcItem ); rcInplaceEdit.top = rcItem.top; rcInplaceEdit.bottom = rcItem.bottom; int nDdExtent = 0; if( mi.IsPopup() ) { nDdExtent = ::GetSystemMetrics(SM_CXHTHUMB); rcInplaceEdit.right += nDdExtent; } if( !pSite->OnCmdNodeResizeH( nInitialResizingStateH, m_hWnd, NULL, pClickedCmdNode, nWidthMin, nWidthMax, rcInplaceEdit // rcItem ) ) return; // resizing is canceled // if( nDdExtent != 0 ) // pClickedCmdNode->TextFieldWidthSet( // pClickedCmdNode->TextFieldWidthGet() - nDdExtent // ); int nSavedIndex = m_nCurIndex; m_nCurIndex = -1; _BuildItems( NULL, m_bTopLevel ); VERIFY( UpdateFromCmdTree( m_hWndCmdReciever, m_pNode, m_bTopLevel ) ); _SyncItems(); ShowWindow( SW_HIDE ); _RecalcLayoutImpl(); VERIFY( SetWindowRgn( NULL, FALSE ) ); ASSERT( !IsWindowVisible() ); _FreeWinObjects(); // adjust screen position CRect rcWnd = _CalcTrackRect(); if( m_rgnWnd.GetSafeHandle() != NULL ) { ASSERT( m_bExcludeAreaSpec ); ASSERT( m_bCombineWithEA ); ASSERT( m_eCombineAlign != __CMBA_NONE ); CRgn rgnTmp; VERIFY( rgnTmp.CreateRectRgn(0,0,0,0) ); rgnTmp.CopyRgn( &m_rgnWnd ); ASSERT( rgnTmp.GetSafeHandle() != NULL ); VERIFY( SetWindowRgn( (HRGN)rgnTmp.Detach(), FALSE ) ); } // if( m_rgnWnd.GetSafeHandle() != NULL ) SetWindowPos( NULL, rcWnd.left, rcWnd.top, rcWnd.Width(), rcWnd.Height(), SWP_NOACTIVATE |SWP_NOZORDER //|SWP_NOOWNERZORDER ); if( m_bScrollingAvailable ) _RecalcLayoutImpl(); ShowWindow( SW_SHOWNA ); UpdateWindow(); _ItemFocusSet( nSavedIndex, FALSE, FALSE, FALSE ); ASSERT( m_pDragSrcNode == NULL ); m_pDragSrcNode = pClickedCmdNode; CClientDC dc( this ); _DoPaint( dc ); m_pDragSrcNode = NULL; return; } // if( nInitialResizingStateH != 0 ) } // if button can be resized #endif // (!defined __EXT_MFC_NO_BUILTIN_TEXTFIELD) ASSERT( m_pDragSrcNode == NULL ); ASSERT( m_nDragSrcIdx < 0 ); m_pDragSrcNode = pClickedCmdNode; m_nDragSrcIdx = nIndex; m_bHelperNoRemoveSrc = false; CRect rcItem( 0, 0, 1, 1 ); _DoResetChainPositions(); m_ptHelperDragStart = point; m_bHelperNoHideChild = true; m_bHelperDragOverPassed = false; _ItemFocusSet( nIndex, TRUE, TRUE, FALSE ); HWND hWndOwn = m_hWnd; ASSERT( hWndOwn != NULL && ::IsWindow(hWndOwn) ); pSite->DoDragCmdNode( this, NULL, m_pDragSrcNode, rcItem ); if( ! ::IsWindow(hWndOwn) ) return; m_pDragSrcNode = NULL; m_bHelperNoHideChild = false; m_nDragSrcIdx = -1; m_bHelperNoRemoveSrc = false; m_bHelperDragOverPassed = false; #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) } void CExtPopupMenuWnd::OnRButtonDown(UINT nFlags, CPoint point) { nFlags; point; #if (!defined __EXT_MFC_NO_CUSTOMIZE) if( (!_FindCustomizeMode()) ) return; int nIndex = _HitTest( point ); if( nIndex < 0 ) return; ASSERT( nIndex < ItemGetCount() ); MENUITEMDATA & mi = _GetItemRef( nIndex ); if( mi.IsSeparator() ) return; _ItemFocusSet( mi.GetIndex(), TRUE, TRUE, FALSE ); CExtCustomizeCmdTreeNode * pNode = mi.GetCmdNode(); ASSERT_VALID( pNode ); CExtCustomizeSite * pSite = _FindCustomizeSite(); ASSERT( pSite != NULL ); CRect rcItem( 0, 0, 1, 1 ); _DoResetChainPositions(); CExtCmdItem * pCmdItem = g_CmdManager->CmdGetPtr( g_CmdManager->ProfileNameFromWnd(m_hWnd), pNode->GetCmdID( false ) ); ASSERT( pCmdItem != NULL ); if( !pSite->CustomizedNodeSet( pNode ) ) return; { // BLOCK CClientDC dc( this ); _DoPaint( dc ); } // BLOCK bool bCanAddRemoveSeparator = (nIndex > 0) ? true : false; bool bDelete = false; HWND hWndOwn = m_hWnd; ASSERT( hWndOwn != NULL && ::IsWindow(hWndOwn) ); if( !pSite->OnCustomizeTreeNode( NULL, pNode, pCmdItem, bDelete, bCanAddRemoveSeparator, this ) ) { if( pSite->CustomizedNodeGet() == pNode ) { VERIFY( pSite->CustomizedNodeSet( NULL ) ); } if( hWndOwn == NULL || (! ::IsWindow(hWndOwn) ) ) return; CClientDC dc( this ); _DoPaint( dc ); return; } VERIFY( pSite->CustomizedNodeSet( NULL ) ); if( !::IsWindow(hWndOwn) ) return; m_nCurIndex = -1; _BuildItems( NULL, m_bTopLevel ); if( bDelete ) { ASSERT_VALID( pNode->GetParentNode() ); int nOwnNodeIndex = pNode->GetOwnIndex(); if( nOwnNodeIndex < (pNode->GetParentNode()->GetNodeCount()-1) ) pNode->GetParentNode()->ElementAt(nOwnNodeIndex+1) ->ModifyFlags( 0, __ECTN_GROUP_START ); pNode->RemoveSelf( pCmdItem ); } ASSERT_VALID( m_pNode ); VERIFY( UpdateFromCmdTree( m_hWndCmdReciever, m_pNode, m_bTopLevel ) ); _SyncItems(); ShowWindow( SW_HIDE ); _RecalcLayoutImpl(); VERIFY( SetWindowRgn( NULL, FALSE ) ); ASSERT( !IsWindowVisible() ); _FreeWinObjects(); // adjust screen position CRect rcWnd = _CalcTrackRect(); if( m_rgnWnd.GetSafeHandle() != NULL ) { ASSERT( m_bExcludeAreaSpec ); ASSERT( m_bCombineWithEA ); ASSERT( m_eCombineAlign != __CMBA_NONE ); CRgn rgnTmp; VERIFY( rgnTmp.CreateRectRgn(0,0,0,0) ); rgnTmp.CopyRgn( &m_rgnWnd ); ASSERT( rgnTmp.GetSafeHandle() != NULL ); VERIFY( SetWindowRgn( (HRGN)rgnTmp.Detach(), FALSE ) ); } // if( m_rgnWnd.GetSafeHandle() != NULL ) SetWindowPos( NULL, rcWnd.left, rcWnd.top, rcWnd.Width(), rcWnd.Height(), SWP_NOACTIVATE |SWP_NOZORDER //|SWP_NOOWNERZORDER ); if( m_bScrollingAvailable ) _RecalcLayoutImpl(); ShowWindow( SW_SHOWNA ); #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) } void CExtPopupMenuWnd::OnShowWindow(BOOL bShow, UINT nStatus) { CExtPopupBaseWnd::OnShowWindow(bShow, nStatus); ASSERT_VALID( this ); if( _FindCustomizeMode() && bShow ) { CClientDC dc( this ); _DoPaint( dc ); } } void CExtPopupMenuWnd::OnCancelMode() { ASSERT_VALID( this ); if( _FindCustomizeMode() ) return; //_OnCancelMode(); CExtPopupMenuSite & _site = GetSite(); _site.DoneInstance(); ASSERT( _site.IsEmpty() ); ASSERT( !_site.IsShutdownMode() ); if( CExtToolControlBar::g_bMenuTracking ) CExtToolControlBar::_CloseTrackingMenus(); } void CExtPopupMenuWnd::_FreeWinObjects() { ASSERT_VALID( this ); if( m_rgnWnd.GetSafeHandle() != NULL ) { VERIFY( m_rgnWnd.DeleteObject() ); } m_ShadowMain.Destroy(); m_ShadowCMBA.Destroy(); _SurfacesDelete(); if( !(::IsWindow(GetSafeHwnd())) ) return; KillTimer(ID_TIMER_ANIMATION); //KillTimer(ID_TIMER_DELAY_SHOW); //KillTimer(ID_TIMER_ITEM_FOCUS_DELAY); //KillTimer(ID_TIMER_SCROLLING); } void CExtPopupMenuWnd::_OnCancelMode( bool bNcDestroy // = false ) { ASSERT_VALID( this ); // update status bar message CExtControlBar::stat_SetMessageString( GetSafeOwner() ); bool bCusomizeMode = _FindCustomizeMode(); if( !bCusomizeMode ) { _CoolTipHide( false ); _FreeWinObjects(); _ReleaseCapture(); } // if( !bCusomizeMode ) INT iter = 0; for( ; iter < m_items_all.GetSize(); iter++ ) { MENUITEMDATA & mi = m_items_all[ iter ]; mi.SetSelected( false ); if( mi.IsPopup() ) { if( mi.GetPopup()->GetSafeHwnd() != NULL ) mi.GetPopup()->_OnCancelMode(); } } m_nCurIndex = IDX_NOTHING; if( bNcDestroy ) return; if( ! ::IsWindow(GetSafeHwnd()) ) return; bool bTopLevel = m_bTopLevel; ShowWindow( SW_HIDE ); if( !bCusomizeMode ) PostMessage( WM_CLOSE ); if( CExtToolControlBar::g_bMenuTracking && bTopLevel && (!bCusomizeMode) ) { CExtToolControlBar::_CloseTrackingMenus(); // CExtToolControlBar * pToolBar = CExtToolControlBar::_GetMenuTrackingBar(); // if( pToolBar != NULL ) // pToolBar->SendMessage( WM_CANCELMODE ); } } void CExtPopupMenuWnd::_ItemFocusSet( int nCurIndex, BOOL bEnableDropChild, BOOL bRepaint, BOOL bSelectAnyInChild // = TRUE ) { ASSERT_VALID( this ); if( m_nCurIndex != nCurIndex ) { _ItemFocusCancel( FALSE ); ASSERT( m_nCurIndex < 0 ); m_nCurIndex = nCurIndex; if( m_nCurIndex < 0 ) return; } bool bResetMessageString = true; bool bWasSet = false; MENUITEMDATA & mi = _GetItemRef(m_nCurIndex); if( mi.IsEnabled() && mi.IsDisplayed() ) { mi.SetSelected( true ); bWasSet = true; // adjust scrolling int nMenuBorderSize = g_PaintManager->GetMenuBorderSize(); if( m_bScrollingAvailable ) { int nMetric; int nMaxScrollPos = _GetMaxScrollPos(); CRect rcItem,rcClient, rcScrollBtnUp,rcScrollBtnDown; _GetItemRect( IDX_SCROLL_TOP, rcScrollBtnUp ); _GetItemRect( IDX_SCROLL_BOTTOM, rcScrollBtnDown ); _GetClientRect( rcClient ); _GetItemRect( m_nCurIndex, rcItem ); nMetric = rcClient.bottom; if( m_nDyScrollOffset != nMaxScrollPos ) { nMetric -= rcScrollBtnDown.Height(); if( m_bExpandAvailable ) { CRect rcExpand; _GetItemRect( IDX_EXPAND, rcExpand ); nMetric -= rcExpand.Height(); } } if( rcItem.bottom >= nMetric ) { m_nDyScrollOffset -= rcItem.bottom - nMetric + nMenuBorderSize*2; } nMetric = rcClient.top; if( m_nDyScrollOffset != 0 ) { nMetric += rcScrollBtnUp.Height(); } if( rcItem.top <= nMetric ) { m_nDyScrollOffset += nMetric - rcItem.top + nMenuBorderSize*2; } if( m_nDyScrollOffset > 0 ) m_nDyScrollOffset = 0; else { if( m_nDyScrollOffset < nMaxScrollPos ) m_nDyScrollOffset = nMaxScrollPos; } } // if( m_bScrollingAvailable ) } // update status bar message CWnd * pWndOwner = GetOwner(); if( pWndOwner != NULL ) { ASSERT_VALID( pWndOwner ); if( bWasSet && (!mi.IsPopup()) && (!mi.IsSeparator()) ) { UINT nCmdID = mi.GetCmdID(); if( CExtCmdManager::IsCommand( nCmdID ) ) { UINT nCmdIDToSend = nCmdID; bool bAbandonSend = false; if( CExtCmdManager::IsSystemCommand( nCmdID ) ) { switch( nCmdID ) { case SC_CLOSE: nCmdIDToSend = AFX_IDS_SCCLOSE; break; case SC_SIZE: nCmdIDToSend = AFX_IDS_SCSIZE; break; case SC_MOVE: nCmdIDToSend = AFX_IDS_SCMOVE; break; case SC_MINIMIZE: nCmdIDToSend = AFX_IDS_SCMINIMIZE; break; case SC_MAXIMIZE: nCmdIDToSend = AFX_IDS_SCMAXIMIZE; break; case SC_RESTORE: nCmdIDToSend = AFX_IDS_SCRESTORE; break; case SC_NEXTWINDOW: nCmdIDToSend = AFX_IDS_SCNEXTWINDOW; break; case SC_PREVWINDOW: nCmdIDToSend = AFX_IDS_SCPREVWINDOW; break; case SC_TASKLIST: nCmdIDToSend = AFX_IDS_SCTASKLIST; break; default: bAbandonSend = true; break; } // switch( nCmdID ) } // if( CExtCmdManager::IsSystemCommand( nCmdID ) ) if( !bAbandonSend ) { CExtControlBar::stat_SetMessageString( pWndOwner, nCmdIDToSend ); bResetMessageString = false; } // if( !bAbandonSend ) } // if( CExtCmdManager::IsCommand( nCmdID ) ) } // if( ! ( mi.IsPopup() || mi.IsSeparator() ) ) if( bResetMessageString ) CExtControlBar::stat_SetMessageString( pWndOwner ); } // if( bWasSet ) if( bRepaint && ::IsWindowVisible(GetSafeHwnd()) ) { // if( m_rgnWnd.GetSafeHandle() != NULL ) // RedrawWindow( // NULL, // &m_rgnWnd, // RDW_INVALIDATE|RDW_UPDATENOW|RDW_NOERASE // |RDW_INTERNALPAINT // ); // else // { CClientDC dc( this ); _DoPaint( dc ); // } } if( mi.IsPopup() ) { if( mi.IsInplaceEdit() ) { HWND hWndInplaceEdit = mi.GetInplaceEditPtr()->GetSafeHwnd(); if( hWndInplaceEdit != NULL && ::IsWindow( hWndInplaceEdit ) && (::GetWindowLong(hWndInplaceEdit,GWL_STYLE)&WS_VISIBLE) != 0 ) bEnableDropChild = false; } // if( mi.IsInplaceEdit() ) } // if( mi.IsPopup() ) else bEnableDropChild = false; if( bWasSet && bEnableDropChild && mi.GetPopup()->_CanStartLevelTracking() ) { // if new popup tracking if( !_FindCustomizeMode() ) _ReleaseCapture(); CRect rectItem; _GetItemRect( m_nCurIndex, rectItem ); rectItem.left -= m_nLeftAreaWidth; CPoint point; point.x = rectItem.right; point.y = rectItem.top, ClientToScreen(&point); ClientToScreen( &rectItem ); ASSERT( mi.GetPopup()->m_pWndParentMenu == this ); bool bDisplayedSuccessfully = false; if( mi.GetPopup()->GetSafeHwnd() == NULL ) { bDisplayedSuccessfully = mi.GetPopup()-> _TrackPopupMenu( ( mi.IsChildCombine() ? TPMX_COMBINE_DEFAULT : 0 ) | ( m_dwTrackFlags & (TPMX_NO_SHADOWS |TPMX_NO_CMD_UI |TPMX_NO_WM_COMMAND ) ) , point.x,point.y, &rectItem, (LPVOID)m_nCurIndex, stat_paint_combined_menu_toolbtn ) ? true : false; } // if( mi.GetPopup()->GetSafeHwnd() == NULL ) else { bDisplayedSuccessfully = true; if( !mi.GetPopup()->IsWindowVisible() ) { mi.GetPopup()->SetWindowPos( &CWnd::wndTopMost, 0, 0, 0, 0, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE |SWP_NOREDRAW |SWP_SHOWWINDOW ); CClientDC dc( mi.GetPopup() ); mi.GetPopup()->_DoPaint( dc ); } // if( !mi.GetPopup()->IsWindowVisible() ) } // else from if( bDisplayedSuccessfully && bSelectAnyInChild ) { // if track-popup succeeded and we need to select any child item int nCountOfPopupItems = mi.GetPopup()->m_items_all.GetSize(); if( nCountOfPopupItems > 0 ) { int nIndex = mi.GetPopup()->_GetNextItem(__NI_ANY); if( nIndex >= 0 ) mi.GetPopup()->_ItemFocusSet( nIndex, FALSE, ( GetSite().GetAnimated() == NULL ) ? TRUE : FALSE ); } } // if track-popup succeeded and we need to select any child item if( bDisplayedSuccessfully && mi.IsInplaceEdit() ) { CClientDC dc( this ); _DoPaint( dc ); } } // if new popup tracking } bool CExtPopupMenuWnd::_CoolTipIsVisible() { ASSERT_VALID( this ); if( _FindCustomizeMode() ) return false; if( !(::IsWindow(GetSafeHwnd())) ) return false; if( CExtPopupMenuSite::g_DefPopupMenuSite.GetCapture() != this ) return false; HWND hWndToolTip = m_wndToolTip.GetSafeHwnd(); if( hWndToolTip != NULL && ::IsWindow( hWndToolTip ) && ::IsWindowVisible( hWndToolTip ) ) return true; return false; } void CExtPopupMenuWnd::_CoolTipHide( bool bAdvOperation // = true ) { ASSERT_VALID( this ); if( !(::IsWindow(GetSafeHwnd())) ) return; HWND hWndToolTip = m_wndToolTip.GetSafeHwnd(); if( hWndToolTip == NULL || (!(::IsWindow(hWndToolTip))) ) return; if( bAdvOperation && ( GetSite().GetAnimated() == NULL ) ) { m_AnimationType = __AT_CONTENT_DISPLAY; _StartAnimation(); } m_wndToolTip.Hide(); } void CExtPopupMenuWnd::_ItemFocusCancel( BOOL bRepaint ) { ASSERT_VALID( this ); if( !_FindCustomizeMode() ) _CoolTipHide(); if( m_nCurIndex < 0 ) { m_nCurIndex = IDX_NOTHING; } // if( m_nCurIndex < 0 ) else { ASSERT( m_nCurIndex < m_items_all.GetSize() ); MENUITEMDATA & mi = _GetItemRef(m_nCurIndex); if( mi.IsInplaceEdit() ) { mi.SetTempSelectedInplaceEditText( NULL ); CWnd * pWndInplace = mi.GetInplaceEditPtr(); if( pWndInplace != NULL ) { ASSERT_VALID( pWndInplace ); ASSERT( pWndInplace->GetSafeHwnd() != NULL && (::IsWindow(pWndInplace->GetSafeHwnd())) ); if( (pWndInplace->GetStyle() & WS_VISIBLE) != 0 ) pWndInplace->ShowWindow( SW_HIDE ); } // if( pWndInplace != NULL ) } mi.SetSelected( false ); m_nCurIndex = IDX_NOTHING; if( mi.IsPopup() ) mi.GetPopup()->_OnCancelMode(); } // else from if( m_nCurIndex < 0 ) // update status bar message CWnd * pWndOwner = GetOwner(); if( pWndOwner != NULL ) CExtControlBar::stat_SetMessageString( pWndOwner ); if( bRepaint && ::IsWindowVisible(GetSafeHwnd()) ) { CClientDC dc( this ); _DoPaint( dc ); } } bool CExtPopupMenuWnd::_CanStartLevelTracking() { ASSERT_VALID( this ); return true; } bool CExtPopupMenuWnd::_OnMouseWheel( WPARAM wParam, LPARAM lParam, bool & bNoEat ) { ASSERT_VALID( this ); wParam; lParam; bNoEat; return true; } bool CExtPopupMenuWnd::_OnMouseMove( UINT nFlags, CPoint point, bool & bNoEat ) { ASSERT_VALID( this ); if( GetSafeHwnd() == NULL ) return false; if( !m_bAnimFinished ) return true; CExtPopupMenuSite & _site = GetSite(); if( _site.IsShutdownMode() || _site.IsEmpty() || _site.GetAnimated() != NULL ) return true; CPoint ptScreenClick( point ); ClientToScreen( &ptScreenClick ); HWND hWndFromPoint = ::WindowFromPoint( ptScreenClick ); if( hWndFromPoint != NULL && (::GetWindowLong(hWndFromPoint,GWL_STYLE)&WS_CHILD) != 0 && ::GetParent(hWndFromPoint) == m_hWnd ) { CWnd * pWnd = CWnd::FromHandlePermanent( hWndFromPoint ); if( pWnd != NULL ) { int nCount = ItemGetCount(); for( int i = 0; i < nCount; i++ ) { MENUITEMDATA & mi = _GetItemRef( i ); if( !mi.IsInplaceEdit() ) continue; if( ((LPVOID)mi.GetInplaceEditPtr()) != ((LPVOID)pWnd) ) continue; if( m_nCurIndex == i ) break; _ItemFocusSet( i, FALSE, TRUE, TRUE ); break; } // for( int i = 0; i < nCount; i++ ) } // if( pWnd != NULL ) bNoEat = true; return false; } HWND hWndFocus = ::GetFocus(); if( hWndFocus != NULL && (::GetWindowLong(hWndFocus,GWL_STYLE)&WS_CHILD) != 0 && ::GetParent(hWndFocus) == m_hWnd ) return true; /* CRect rectWindow; GetWindowRect( &rectWindow ); ScreenToClient( &rectWindow ); if( !rectWindow.PtInRect(point) ) */ if( !_PtInWndArea(point) ) { // _ItemFocusCancel( TRUE ); if( m_pWndParentMenu != NULL && m_pWndParentMenu->GetSafeHwnd() != NULL ) { ASSERT_VALID( m_pWndParentMenu ); ClientToScreen( &point ); m_pWndParentMenu->ScreenToClient( &point ); if( m_pWndParentMenu->_OnMouseMove( nFlags, point, bNoEat ) ) { if( bNoEat ) return false; _OnCancelMode(); return true; } } return false; } int nCurIndex = _HitTest(point); if( nCurIndex == IDX_EXPAND ) { _ItemFocusCancel( TRUE ); if( g_bMenuDelayExpanding ) { _SetCapture(); if( m_nWaitingExpandTickCount == 0 ) { SetTimer( ID_TIMER_DELAY_EXPAND, ID_TOTAL_DELAY_EXPAND/ID_FREQ_DELAY_EXPAND, NULL ); m_nWaitingExpandTickCount = 1; } } // if( g_bMenuDelayExpanding ) return true; } if( _StartScrolling(nCurIndex) ) return true; if( nCurIndex >= 0 ) { #ifdef _DEBUG int nCountOfItems = m_items_all.GetSize(); ASSERT( nCurIndex < nCountOfItems ); #endif // _DEBUG MENUITEMDATA & mi = _GetItemRef(nCurIndex); if( (!mi.IsEnabled()) || mi.IsSeparator() ) return false; int nOldCurIndex = m_nCurIndex; if( nOldCurIndex != nCurIndex ) { _ItemFocusDelay(); _SetCapture(); _ItemFocusSet( nCurIndex, FALSE, TRUE ); MENUITEMDATA & mi = _GetItemRef(nCurIndex); if( mi.IsPopup() ) { m_wndToolTip.Hide(); if( mi.GetPopup()->GetSafeHwnd() == NULL ) _ItemFocusDelay( nCurIndex ); return true; } if( g_bMenuShowCoolTips && nCurIndex != nOldCurIndex && GetSite().GetCapture() == this ) { CExtSafeString sTipText = mi.GetTip(); if( !sTipText.IsEmpty() ) { CRect rcItem; _GetItemRect(nCurIndex,rcItem); ClientToScreen( &rcItem ); m_wndToolTip.SetText( sTipText ); VERIFY( m_wndToolTip.Show( this, rcItem ) ); } // if( !sTipText.IsEmpty() ) } // if( g_bMenuShowCoolTips .... } // if( nOldCurIndex != nCurIndex ) return (nOldCurIndex == nCurIndex) ? false : true; } // if( nCurIndex >= 0 ) return false; } void CExtPopupMenuWnd::_ItemFocusDelay( int nItemIndex // = IDX_NOTHING ) { ASSERT_VALID( this ); if( !(::IsWindow(GetSafeHwnd())) ) return; if( m_nDelayedFocusItemIndex != nItemIndex ) { if( m_nDelayedFocusItemIndex >= 0 ) KillTimer( ID_TIMER_ITEM_FOCUS_DELAY ); //m_nDelayedFocusItemIndex = IDX_NOTHING; } if( nItemIndex < 0 ) { m_nDelayedFocusItemIndex = IDX_NOTHING; return; } if( m_nDelayedFocusItemIndex == nItemIndex ) return; ASSERT( nItemIndex>=0 && nItemIndex<m_items_all.GetSize() ); m_nDelayedFocusItemIndex = nItemIndex; ASSERT( _GetItemRef(m_nDelayedFocusItemIndex).IsPopup() ); SetTimer( ID_TIMER_ITEM_FOCUS_DELAY, ID_PERIOD_ITEM_FOCUS_DELAY, NULL ); } int CExtPopupMenuWnd::_GetMaxScrollPos() { ASSERT_VALID( this ); ASSERT( m_bScrollingAvailable ); CRect rcClient; _GetClientRect( &rcClient ); int nClientHeight = rcClient.Height(); int nMenuBorderSize = g_PaintManager->GetMenuBorderSize(); int nMenuShadowSize = _GetPopupShadowSize(); int nMaxScrollPos = m_sizeFullItems.cy; nMaxScrollPos += nMenuBorderSize*2; nMaxScrollPos += nMenuShadowSize; nMaxScrollPos -= nClientHeight; ASSERT( nMaxScrollPos > 0 ); if( m_bExpandAvailable ) nMaxScrollPos += _GetSpecBtnHeight(); // xpand btn return -nMaxScrollPos; } void CExtPopupMenuWnd::OnTimer(UINT nIDEvent) { ASSERT_VALID( this ); switch( nIDEvent ) { case ID_TIMER_DELAY_EXPAND: { if( m_nWaitingExpandTickCount < ID_TOTAL_DELAY_EXPAND ) { if( m_nWaitingExpandTickCount <= 1 ) m_nWaitingExpandTickCount = 0; m_nWaitingExpandTickCount += ID_FREQ_DELAY_EXPAND; return; } VERIFY( KillTimer(ID_TIMER_DELAY_EXPAND) ); m_nWaitingExpandTickCount = 0; if( m_bExpandAvailable && (!m_bExpandWasPressed) && ( GetSite().GetAnimated() == NULL ) ) { // if expand can be performed CPoint point; if( ! ::GetCursorPos(&point) ) return; ScreenToClient( &point ); CRect rcExpand; _GetItemRect( IDX_EXPAND, rcExpand ); if( rcExpand.PtInRect(point) ) _DoExpand(); } // if expand can be performed return; } //case ID_TIMER_DELAY_EXPAND case ID_TIMER_SCROLLING: { _ItemFocusDelay(); if( m_nCurIndex >= 0 ) _ItemFocusCancel(TRUE); CPoint point; if( ! ::GetCursorPos(&point) ) return; ScreenToClient( &point ); m_nScrollingDirection = 0; CRect rcItem; _GetItemRect(IDX_SCROLL_TOP,rcItem); if( rcItem.PtInRect(point) ) m_nScrollingDirection = __SCROLLING_PIXEL_STEP; else { _GetItemRect(IDX_SCROLL_BOTTOM,rcItem); if( rcItem.PtInRect(point) ) m_nScrollingDirection = (-__SCROLLING_PIXEL_STEP); } m_nDyScrollOffset += m_nScrollingDirection; bool bKillThisTimer = (m_nScrollingDirection == 0) ? true : false; if( m_nDyScrollOffset > 0 ) { m_nDyScrollOffset = 0; bKillThisTimer = true; } else { int nMaxScrollPos = _GetMaxScrollPos(); if( m_nDyScrollOffset < nMaxScrollPos ) { m_nDyScrollOffset = nMaxScrollPos; bKillThisTimer = true; } } if( bKillThisTimer ) { VERIFY( KillTimer(ID_TIMER_SCROLLING) ); m_nScrollingDirection = 0; } Invalidate( FALSE ); return; } // case ID_TIMER_SCROLLING case ID_TIMER_ITEM_FOCUS_DELAY: { if( GetSite().GetAnimated() != NULL ) return; KillTimer( ID_TIMER_ITEM_FOCUS_DELAY ); if( GetSite().IsShutdownMode() ) return; if( m_nDelayedFocusItemIndex >= 0 ) { ASSERT( m_nDelayedFocusItemIndex>=0 && m_nDelayedFocusItemIndex<m_items_all.GetSize() ); ASSERT( _GetItemRef(m_nDelayedFocusItemIndex).IsPopup() ); CRect rcItem; _GetItemRect(m_nDelayedFocusItemIndex,rcItem); CPoint point; if( ! ::GetCursorPos( &point ) ) return; ScreenToClient( &point ); if( rcItem.PtInRect(point) ) { _ItemFocusSet( m_nDelayedFocusItemIndex, TRUE, TRUE, FALSE ); } } // if( m_nDelayedFocusItemIndex >= 0 ) m_nDelayedFocusItemIndex = IDX_NOTHING; return; } // case ID_TIMER_ITEM_FOCUS_DELAY default: CExtPopupBaseWnd::OnTimer(nIDEvent); break; // default } // switch( nIDEvent ) } CExtPopupMenuWnd * CExtPopupMenuWnd::_GetCapture() { return GetSite().GetCapture(); } void CExtPopupMenuWnd::_SetCapture() { ASSERT_VALID( this ); ASSERT( !_FindCustomizeMode() ); CExtPopupMenuSite & _site = GetSite(); if( GetSafeHwnd() != NULL ) { ASSERT( ::IsWindow(GetSafeHwnd()) ); _site.SetCapture( this ); } else _site.SetCapture( NULL ); } void CExtPopupMenuWnd::_ReleaseCapture() { ASSERT_VALID( this ); ASSERT( !_FindCustomizeMode() ); CExtPopupMenuSite & _site = GetSite(); if( _site.IsEmpty() || _site.IsShutdownMode() ) return; if( _site.GetCapture() == this ) _site.SetCapture( NULL ); } int CExtPopupMenuWnd::_GetNextItem( next_item_t nit ) { ASSERT_VALID( this ); int nCountOfItems = m_items_all.GetSize(); bool bCanExpand = false; if( m_bExpandAvailable && (!m_bExpandWasPressed) ) { if( IsAllItemsRarelyUsed() ) return IDX_EXPAND; bCanExpand = true; } if( nit == __NI_NOTHING || nCountOfItems == 0 ) { if( bCanExpand ) return IDX_EXPAND; return IDX_NOTHING; } if( nit == __NI_ANY && m_nCurIndex >= 0 ) return m_nCurIndex; if( m_nCurIndex < 0 ) { INT iter = 0; for( ; iter < m_items_all.GetSize(); ++iter ) { MENUITEMDATA & mi = m_items_all[ iter ]; if( mi.IsEnabled() && mi.IsDisplayed() ) return mi.GetIndex(); } if( bCanExpand ) return IDX_EXPAND; return IDX_NOTHING; } if( nit == __NI_NEXT ) { if( nCountOfItems < 2 ) { if( bCanExpand ) return IDX_EXPAND; return IDX_NOTHING; } INT iter = m_nCurIndex + 1; for( ; iter < m_items_all.GetSize(); ++iter ) { MENUITEMDATA & mi = m_items_all[ iter ]; if( mi.IsEnabled() && mi.IsDisplayed() ) return mi.GetIndex(); } if( bCanExpand ) return IDX_EXPAND; if( m_nCurIndex == 0 ) return IDX_NOTHING; iter = 0; INT iter2 = m_nCurIndex - 1; do { MENUITEMDATA & mi = m_items_all[ iter ]; if( mi.IsEnabled() && mi.IsDisplayed() ) return mi.GetIndex(); iter++; } while( iter != iter2 ); return IDX_NOTHING; } if( nit == __NI_PREV ) { if( nCountOfItems < 2 ) return IDX_NOTHING; if( m_nCurIndex != 0 ) { int nIndex = m_nCurIndex - 1; INT iter = nIndex; for( ; true; ) { MENUITEMDATA & mi = m_items_all[ iter ]; if( mi.IsEnabled() && mi.IsDisplayed() ) return mi.GetIndex(); if( nIndex == 0 ) break; --iter; --nIndex; } } int nIndex = m_nCurIndex + 1; INT iter2 = nIndex; INT iter = m_items_all.GetSize() - 1; do { MENUITEMDATA & mi = m_items_all[ iter ]; if( mi.IsEnabled() && mi.IsDisplayed() ) return mi.GetIndex(); iter--; } while( iter != iter2 ); return IDX_NOTHING; } return IDX_NOTHING; } bool CExtPopupMenuWnd::_OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags, bool & bNoEat ) { ASSERT_VALID( this ); ASSERT( m_hWndCmdReciever != NULL ); ASSERT( ::IsWindow(m_hWndCmdReciever) ); nRepCnt; if( GetSafeHwnd() == NULL ) return true; if( !m_bAnimFinished ) return true; CExtPopupMenuSite & _site = GetSite(); if( _site.IsShutdownMode() || _site.IsEmpty() || _site.GetAnimated() != NULL ) return true; HWND hWndFocus = ::GetFocus(); if( hWndFocus != NULL && (::GetWindowLong(hWndFocus,GWL_STYLE)&WS_CHILD) != 0 && ::GetParent(hWndFocus) == m_hWnd ) { bool bAlt = ( (::GetAsyncKeyState(VK_MENU)&0x8000) != 0 ) ? true : false; bool bCtrl = ( (::GetAsyncKeyState(VK_CONTROL)&0x8000) != 0 ) ? true : false; bool bShift = ( (::GetAsyncKeyState(VK_SHIFT)&0x8000) != 0 ) ? true : false; if( bAlt ) PostMessage( WM_CANCELMODE ); else if( nChar == VK_ESCAPE ) SetFocus(); else if( (nChar == VK_INSERT || nChar == _T('C')) && bCtrl ) ::SendMessage( hWndFocus, WM_COPY, 0, 0 ); else if( ( nChar == _T('X') && bCtrl ) || ( nChar == VK_DELETE && bShift ) ) ::SendMessage( hWndFocus, WM_CUT, 0, 0 ); else if( ( nChar == _T('V') && bCtrl ) || ( nChar == VK_INSERT && bShift ) ) ::SendMessage( hWndFocus, WM_PASTE, 0, 0 ); else if( nChar == VK_DELETE ) ::SendMessage( hWndFocus, CExtPopupMenuWnd::CInPlaceEditWnd::g_nMsgDeleteSelection, 0, 0 ); else if( nChar == _T('A') && bCtrl ) ::SendMessage( hWndFocus, CExtPopupMenuWnd::CInPlaceEditWnd::g_nMsgSelectAll, 0, 0 ); else bNoEat = true; return (!bNoEat); } next_item_t nit = __NI_NOTHING; switch( nChar ) { case VK_MENU: _EndSequence(); return true; case VK_SPACE: return true; case VK_RETURN: { if( m_nCurIndex < 0 ) return true; // break; MENUITEMDATA & mi = _GetItemRef(m_nCurIndex); if( mi.IsInplaceEdit() ) { CWnd * pWndInplace = mi.GetInplaceEditPtr(); if( pWndInplace != NULL ) { ASSERT_VALID( pWndInplace ); ASSERT( pWndInplace->GetSafeHwnd() != NULL && (::IsWindow(pWndInplace->GetSafeHwnd())) ); if( mi.IsAllowInplaceEditActivation() ) { if( (pWndInplace->GetStyle() & WS_VISIBLE) == 0 ) { CRect rcInplaceEdit; _GetItemRect( m_nCurIndex, rcInplaceEdit ); rcInplaceEdit = mi.AdjustInplaceEditRect( rcInplaceEdit ); pWndInplace->SetWindowPos( NULL, rcInplaceEdit.left, rcInplaceEdit.top, rcInplaceEdit.Width(), rcInplaceEdit.Height(), SWP_NOZORDER|SWP_NOOWNERZORDER |SWP_NOACTIVATE|SWP_SHOWWINDOW ); } // if( (pWndInplace->GetStyle() & WS_VISIBLE) == 0 ) pWndInplace->SetFocus(); } // if( mi.IsAllowInplaceEditActivation() ) } // if( pWndInplace != NULL ) return true; } if( mi.IsExtraMark() ) { ASSERT( mi.GetExtraMarkCallback() != NULL ); mi.GetExtraMarkCallback()( this, &mi ); CClientDC dc( this ); _DoPaint( dc ); return true; } // if( mi.IsExtraMark() ) if( mi.IsExecutableCmdID() ) { if( !( mi.GetCmdDeliverCb() != NULL && mi.GetCmdDeliverCb()( this, &mi ) ) ) _EndSequence( mi.GetCmdID(), mi.GetCmdReciever() ); return true; } } // case VK_RETURN case VK_RIGHT: { bool bSendChangeMenu = false; if( m_nCurIndex < 0 ) { if( m_items_all.GetSize() == 0 ) return true; // false; // nit = __NI_ANY; bSendChangeMenu = true; } else { MENUITEMDATA & mi = _GetItemRef(m_nCurIndex); if( !mi.IsPopup() ) { bSendChangeMenu = true; } else { if( mi.GetPopup()->GetSafeHwnd() == NULL ) { _ItemFocusDelay(); _ItemFocusSet( m_nCurIndex, TRUE, TRUE ); } } } if( bSendChangeMenu && nChar==VK_RIGHT ) { ASSERT( m_hWndCmdReciever != NULL ); ASSERT( ::IsWindow(m_hWndCmdReciever) ); if( CExtToolControlBar::g_bMenuTracking ) ::PostMessage( m_hWndCmdReciever, CExtPopupMenuWnd::g_nMsgPopupNext, 0, LPARAM( this ) ); return true; } } break; // case VK_RIGHT case VK_LEFT: if( m_pWndParentMenu == NULL ) { if( CExtToolControlBar::g_bMenuTracking ) ::PostMessage( m_hWndCmdReciever, CExtPopupMenuWnd::g_nMsgPopupPrev, 0, LPARAM( this ) ); return true; } else { ASSERT( !m_bTopLevel ); int nParentCurIndex = m_pWndParentMenu->m_nCurIndex; ASSERT( nParentCurIndex >= 0 && nParentCurIndex <= m_pWndParentMenu->m_items_all.GetSize() ); m_pWndParentMenu->_ItemFocusCancel( FALSE ); m_pWndParentMenu->_ItemFocusSet( nParentCurIndex, FALSE, TRUE ); m_pWndParentMenu->_SetCapture(); return true; } case VK_ESCAPE: _EndSequence(); return true; // case VK_ESCAPE case VK_UP: nit = __NI_PREV; break; // case VK_UP case VK_DOWN: if( IsKeyPressed( VK_CONTROL ) ) { if( m_bExpandAvailable ) _DoExpand(); return true; } nit = __NI_NEXT; break; // case VK_DOWN case VK_NEXT: nit = __NI_PAGE_DOWN; break; // case VK_NEXT case VK_PRIOR: nit = __NI_PAGE_UP; break; // case VK_PRIOR default: //if( _istalnum(nChar) ) { // BLOCK: try analyze quick char access if( IsKeyPressed(VK_SHIFT) || IsKeyPressed(VK_CONTROL) || IsKeyPressed(VK_MENU) || ( (nFlags & (1<<29)) != 0 ) // ALT pressed? ) return false; BYTE lpKeyState[256]; ::GetKeyboardState( lpKeyState ); UINT wScanCode = ::MapVirtualKey( nChar, 0 ); HKL hKeyboardLayout = ::GetKeyboardLayout( ( ::AfxGetThread() ) -> m_nThreadID ); #if (defined _UNICODE) TCHAR szChar[2] = { _T('\0'), _T('\0') }; ::ToUnicodeEx( nChar, wScanCode, lpKeyState, szChar, 1, 1, hKeyboardLayout ); WORD nMapped = WORD( szChar[0] ); #else WORD nMapped = 0; ::ToAsciiEx( nChar, wScanCode, lpKeyState, &nMapped, 1, hKeyboardLayout ); //TCHAR szChar[2] = { (TCHAR)nMapped, _T('\0') }; #endif INT nNextIdx = ItemFindByAccessChar( (TCHAR)nMapped, m_nCurIndex // (m_nCurIndex >= 0) ? m_nCurIndex : -1 ); if( nNextIdx < 0 && m_nCurIndex >= 0 && ItemFindByAccessChar( (TCHAR)nMapped, -1 ) == m_nCurIndex ) { // if only 1 with this char MENUITEMDATA & mi = _GetItemRef( m_nCurIndex ); if( mi.IsInplaceEdit() && (!mi.IsPopup()) ) { CWnd * pWndInplace = mi.GetInplaceEditPtr(); if( pWndInplace != NULL ) { ASSERT_VALID( pWndInplace ); ASSERT( pWndInplace->GetSafeHwnd() != NULL && (::IsWindow(pWndInplace->GetSafeHwnd())) ); if( mi.IsAllowInplaceEditActivation() ) { if( (pWndInplace->GetStyle() & WS_VISIBLE) == 0 ) { CRect rcInplaceEdit; _GetItemRect( m_nCurIndex, rcInplaceEdit ); rcInplaceEdit = mi.AdjustInplaceEditRect( rcInplaceEdit ); pWndInplace->SetWindowPos( NULL, rcInplaceEdit.left, rcInplaceEdit.top, rcInplaceEdit.Width(), rcInplaceEdit.Height(), SWP_NOZORDER|SWP_NOOWNERZORDER |SWP_NOACTIVATE|SWP_SHOWWINDOW ); } // if( (pWndInplace->GetStyle() & WS_VISIBLE) == 0 ) pWndInplace->SetFocus(); } // if( mi.IsAllowInplaceEditActivation() ) } // if( pWndInplace != NULL ) return true; } // if( mi.IsInplaceEdit() && (!mi.IsPopup()) ) if( mi.IsExtraMark() ) { ASSERT( mi.GetExtraMarkCallback() != NULL ); mi.GetExtraMarkCallback()( this, &mi ); CClientDC dc( this ); _DoPaint( dc ); return true; } // if( mi.IsExtraMark() ) if( mi.IsExecutableCmdID() ) { if( !( mi.GetCmdDeliverCb() != NULL && mi.GetCmdDeliverCb()( this, &mi ) ) ) _EndSequence( mi.GetCmdID(), mi.GetCmdReciever() ); return true; } // if( mi.IsExecutableCmdID() ) } // if only 1 with this char if( m_nCurIndex != nNextIdx && nNextIdx >= 0 ) { _ItemFocusSet( nNextIdx, TRUE, TRUE ); if( ItemFindByAccessChar( (TCHAR)nMapped, nNextIdx ) < 0 ) { // if only 1 with this char MENUITEMDATA & mi = _GetItemRef( nNextIdx ); if( mi.IsInplaceEdit() && (!mi.IsPopup()) ) { CWnd * pWndInplace = mi.GetInplaceEditPtr(); if( pWndInplace != NULL ) { ASSERT_VALID( pWndInplace ); ASSERT( pWndInplace->GetSafeHwnd() != NULL && (::IsWindow(pWndInplace->GetSafeHwnd())) ); if( mi.IsAllowInplaceEditActivation() ) { if( (pWndInplace->GetStyle() & WS_VISIBLE) == 0 ) { CRect rcInplaceEdit; _GetItemRect( nNextIdx, rcInplaceEdit ); rcInplaceEdit = mi.AdjustInplaceEditRect( rcInplaceEdit ); pWndInplace->SetWindowPos( NULL, rcInplaceEdit.left, rcInplaceEdit.top, rcInplaceEdit.Width(), rcInplaceEdit.Height(), SWP_NOZORDER|SWP_NOOWNERZORDER |SWP_NOACTIVATE|SWP_SHOWWINDOW ); } // if( (pWndInplace->GetStyle() & WS_VISIBLE) == 0 ) pWndInplace->SetFocus(); } // if( mi.IsAllowInplaceEditActivation() ) } // if( pWndInplace != NULL ) return true; } // if( mi.IsInplaceEdit() && (!mi.IsPopup()) ) if( mi.IsExtraMark() ) { ASSERT( mi.GetExtraMarkCallback() != NULL ); mi.GetExtraMarkCallback()( this, &mi ); CClientDC dc( this ); _DoPaint( dc ); return true; } // if( mi.IsExtraMark() ) if( mi.IsExecutableCmdID() ) { if( !( mi.GetCmdDeliverCb() != NULL && mi.GetCmdDeliverCb()( this, &mi ) ) ) _EndSequence( mi.GetCmdID(), mi.GetCmdReciever() ); return true; } // if( mi.IsExecutableCmdID() ) } // if only 1 with this char return true; } } // BLOCK: try analyze quick char access } // switch( nChar ) if( nit != __NI_NOTHING ) { int nItemIndex = _GetNextItem(nit); if( m_items_all.GetSize() > 0 && nItemIndex >= 0 && nItemIndex != m_nCurIndex ) { _ItemFocusSet( nItemIndex, FALSE, TRUE ); return true; // false; } if( nItemIndex == IDX_EXPAND ) { ASSERT( m_bExpandAvailable ); ASSERT( !m_bExpandWasPressed ); int nItemIndex = m_nCurIndex; _DoExpand(); if( nItemIndex >= 0 ) { _ItemFocusSet( nItemIndex, FALSE, //m_bAnimFinished ( GetSite().GetAnimated() == NULL ) ? TRUE : FALSE ); int i = _GetNextItem(__NI_NEXT); _ItemFocusSet( (i>0) ? i : nItemIndex, FALSE, //m_bAnimFinished ( GetSite().GetAnimated() == NULL ) ? TRUE : FALSE ); } return true; } } // if( nit != __NI_NOTHING ) return false; } INT CExtPopupMenuWnd::ItemFindByText( __EXT_MFC_SAFE_LPCTSTR sText, INT nStartIdx, // = -1 BOOL bRestartAt0 // = TRUE ) const { bRestartAt0; ASSERT_VALID( this ); if( sText == NULL || sText[0] == _T('\0') ) { ASSERT( FALSE ); return -1; } int nCount = m_items_all.GetSize(); //ItemGetCount(); int nIdx = (nStartIdx >= 0) ? (nStartIdx + 1) : 0; for( ; nIdx < nCount; nIdx++ ) { const MENUITEMDATA & mi = _GetItemRef(nIdx); // if( !mi.AccelCharIsSet() ) // continue; // if( !mi.IsDisplayed() ) // continue; // if( !mi.IsEnabled() ) // continue; if( _tcscmp( sText, mi.GetText() ) == 0 ) { if( nStartIdx != nIdx ) return nIdx; } } // for( nIdx = nStartIdx; nIdx < nCount; nIdx++ ) if( nStartIdx == 0 ) return -1; for( nIdx = 0; nIdx<nStartIdx; nIdx++ ) { const MENUITEMDATA & mi = _GetItemRef(nIdx); // if( !mi.AccelCharIsSet() ) // continue; // if( !mi.IsDisplayed() ) // continue; // if( !mi.IsEnabled() ) // continue; if( _tcscmp( sText, mi.GetText() ) == 0 ) { if( nStartIdx != nIdx ) return nIdx; } } // for( nIdx = 0; nIdx<nStartIdx; nIdx++ ) return -1; } INT CExtPopupMenuWnd::ItemFindByAccessChar( __EXT_MFC_SAFE_TCHAR chrAccess, INT nStartIdx, // = -1 BOOL bRestartAt0 // = TRUE ) const { ASSERT_VALID( this ); bRestartAt0; if( chrAccess == _T('0') ) return -1; TCHAR szChar[2] = { chrAccess, _T('\0') }; ::CharUpper( szChar ); int cAccelSearch = szChar[0]; //toupper(nChar); if( cAccelSearch == 0 ) return -1; int nCount = m_items_all.GetSize(); //ItemGetCount(); int nIdx = (nStartIdx >= 0) ? (nStartIdx + 1) : 0; for( ; nIdx < nCount; nIdx++ ) { const MENUITEMDATA & mi = _GetItemRef(nIdx); if( !mi.AccelCharIsSet() ) continue; if( !mi.IsDisplayed() ) continue; if( !mi.IsEnabled() ) continue; TCHAR cAccel = mi.AccelCharGet(); if( cAccelSearch == cAccel // _totupper(cAccel) ) { if( nStartIdx != nIdx ) return nIdx; } } // for( nIdx = nStartIdx; nIdx < nCount; nIdx++ ) if( nStartIdx == 0 ) return -1; for( nIdx = 0; nIdx<nStartIdx; nIdx++ ) { const MENUITEMDATA & mi = _GetItemRef(nIdx); if( !mi.AccelCharIsSet() ) continue; if( !mi.IsDisplayed() ) continue; if( !mi.IsEnabled() ) continue; TCHAR cAccel = mi.AccelCharGet(); if( cAccelSearch == cAccel // _totupper(cAccel) ) { if( nStartIdx != nIdx ) return nIdx; } } // for( nIdx = 0; nIdx<nStartIdx; nIdx++ ) return -1; } BOOL CExtPopupMenuWnd::IsCmdKeyActivation( LPARAM lParam // = 0 ) { if( (lParam & (1<<29)) != 0 ) // ALT pressed? return TRUE; static int nTestKeys[] = { VK_MENU,VK_RMENU,VK_LMENU, VK_CONTROL,VK_RCONTROL,VK_LCONTROL, VK_SHIFT,VK_RSHIFT,VK_LSHIFT }; for( int i=0; i<sizeof(nTestKeys)/sizeof(int); i++ ) { if( IsKeyPressed(nTestKeys[i]) ) { // if( nTestKeys[i] == VK_CONTROL // || nTestKeys[i] == VK_RCONTROL // || nTestKeys[i] == VK_LCONTROL // ) // { // if( IsKeyPressed(VK_DOWN) ) // return FALSE; // } return TRUE; } } return FALSE; } INT CExtPopupMenuWnd::ItemGetCount() const { ASSERT_VALID( this ); ASSERT_VALID( this ); // ASSERT( GetTrackingMenu() != this ); INT nCountOfItems = m_items_all.GetSize(); return nCountOfItems; } INT CExtPopupMenuWnd::ItemFindPosForCmdID( UINT nCmdID, INT nPosStart // = -1 ) const { ASSERT_VALID( this ); INT nPos = (nPosStart < 0) ? 0 : nPosStart + 1; INT nCount = ItemGetCount(); for( ; nPos < nCount; nPos++ ) { UINT nCmdID2 = ItemGetCmdID( nPos ); if( nCmdID == nCmdID2 ) return nPos; } return -1; // not found } UINT CExtPopupMenuWnd::ItemGetCmdID( // menu_item_type_t values can be returned INT nPos ) const { ASSERT_VALID( this ); ASSERT( GetTrackingMenu() != this ); INT nCountOfItems = ItemGetCount(); if( nPos < 0 || nPos >= nCountOfItems ) { ASSERT( FALSE ); return TYPE_SEPARATOR; } const MENUITEMDATA & mi = _GetItemRef(nPos); UINT nCmdID = mi.GetCmdID(); return nCmdID; } bool CExtPopupMenuWnd::ItemSetPopupIcon( INT nPos, HICON hIcon // = NULL // no icon by default ) { ASSERT_VALID( this ); ASSERT( GetTrackingMenu() != this ); INT nCountOfItems = ItemGetCount(); if( nPos < 0 || nPos >= nCountOfItems ) { ASSERT( FALSE ); return false; } MENUITEMDATA & mi = _GetItemRef(nPos); return mi.SetPopupIcon( hIcon ); } bool CExtPopupMenuWnd::ItemSetPopupText( INT nPos, __EXT_MFC_SAFE_LPCTSTR sText // NULL if empty ) { ASSERT_VALID( this ); ASSERT( GetTrackingMenu() != this ); INT nCountOfItems = ItemGetCount(); if( nPos < 0 || nPos >= nCountOfItems ) { ASSERT( FALSE ); return false; } MENUITEMDATA & mi = _GetItemRef(nPos); if( !mi.SetPopupText( sText ) ) return false; mi.MeasureItem(); return true; } bool CExtPopupMenuWnd::ItemSetPopupAccelText( INT nPos, __EXT_MFC_SAFE_LPCTSTR sText // NULL if empty ) { ASSERT_VALID( this ); ASSERT( GetTrackingMenu() != this ); INT nCountOfItems = ItemGetCount(); if( nPos < 0 || nPos >= nCountOfItems ) { ASSERT( FALSE ); return false; } MENUITEMDATA & mi = _GetItemRef(nPos); return mi.SetPopupAccelText( sText ); } HICON CExtPopupMenuWnd::ItemGetIcon( INT nPos ) const { ASSERT_VALID( this ); ASSERT( GetTrackingMenu() != this ); INT nCountOfItems = ItemGetCount(); if( nPos < 0 || nPos >= nCountOfItems ) { ASSERT( FALSE ); return NULL; } const MENUITEMDATA & mi = _GetItemRef(nPos); CExtCmdIcon * pIcon = ((MENUITEMDATA &)mi).GetIconPtr(); if( pIcon == NULL || pIcon->IsEmpty() ) return NULL; return pIcon->GetIcon(); } CExtPopupMenuWnd::MENUITEMDATA & CExtPopupMenuWnd::ItemGetInfo( INT nPos ) { ASSERT_VALID( this ); INT nCountOfItems = ItemGetCount(); if( nPos < 0 || nPos >= nCountOfItems ) { ASSERT( FALSE ); AfxThrowNotSupportedException(); } return _GetItemRef( nPos ); } const CExtPopupMenuWnd::MENUITEMDATA & CExtPopupMenuWnd::ItemGetInfo( INT nPos ) const { ASSERT_VALID( this ); INT nCountOfItems = ItemGetCount(); if( nPos < 0 || nPos >= nCountOfItems ) { ASSERT( FALSE ); AfxThrowNotSupportedException(); } return _GetItemRef( nPos ); } CExtSafeString CExtPopupMenuWnd::ItemGetText( INT nPos ) const { ASSERT_VALID( this ); ASSERT( GetTrackingMenu() != this ); INT nCountOfItems = ItemGetCount(); if( nPos < 0 || nPos >= nCountOfItems ) { ASSERT( FALSE ); return CExtSafeString( _T("") ); } const MENUITEMDATA & mi = _GetItemRef(nPos); return CExtSafeString( mi.GetText() ); } CExtSafeString CExtPopupMenuWnd::ItemGetAccelText( INT nPos ) const { ASSERT_VALID( this ); ASSERT( GetTrackingMenu() != this ); INT nCountOfItems = ItemGetCount(); if( nPos < 0 || nPos >= nCountOfItems ) { ASSERT( FALSE ); return CExtSafeString( _T("") ); } const MENUITEMDATA & mi = _GetItemRef(nPos); return CExtSafeString( mi.GetAccelText() ); } bool CExtPopupMenuWnd::ItemIsDisplayed( INT nPos ) const { const MENUITEMDATA & mi = _GetItemRef( nPos ); return mi.IsDisplayed(); } void CExtPopupMenuWnd::ItemSetDisplayed( INT nPos, bool bForceDisplayed // = true ) { MENUITEMDATA & mi = _GetItemRef( nPos ); mi.SetForceDisplayed( bForceDisplayed ); _SyncItems(); } CExtPopupMenuWnd * CExtPopupMenuWnd::ItemGetPopup( INT nPos ) { ASSERT_VALID( this ); ASSERT( GetTrackingMenu() != this ); const CExtPopupMenuWnd * pChild = ((const CExtPopupMenuWnd *)this)-> ItemGetPopup( nPos ); if( pChild == NULL ) return NULL; return const_cast <CExtPopupMenuWnd *> (pChild); } void CExtPopupMenuWnd::_DoExpand() { ASSERT_VALID( this ); ASSERT( !_FindCustomizeMode() ); _ItemFocusDelay(); _CoolTipHide( false ); if( ( GetSite().GetAnimated() != NULL ) || _CoolTipIsVisible() ) return; ASSERT( m_bExpandAvailable ); ASSERT( !m_bExpandWasPressed ); ASSERT( ::IsWindow(GetSafeHwnd()) ); ASSERT( ( GetSite().GetAnimated() == NULL ) ); m_bExpandWasPressed = true; CSize m_sizeFullItems2 = m_sizeFullItems; _SyncItems(); _RecalcLayoutImpl(); if( m_sizeFullItems != m_sizeFullItems2 ) { // if size of all items was changed ASSERT( m_sizeFullItems.cx >= m_sizeFullItems2.cx && m_sizeFullItems.cy >= m_sizeFullItems2.cy ); CRect rcWndOld; GetWindowRect( &rcWndOld ); VERIFY( SetWindowRgn( NULL, FALSE ) ); ShowWindow( SW_HIDE ); ASSERT( !IsWindowVisible() ); if( !rcWndOld.IsRectEmpty() ) { CWnd * pWndTLP = GetTopLevelParent(); if( pWndTLP != NULL ) { ASSERT_VALID( pWndTLP ); if( pWndTLP->IsWindowVisible() ) { CRect rcTLP; pWndTLP->GetWindowRect( &rcTLP ); if( !rcTLP.IsRectEmpty() ) { CRect rcIntersection; if( rcIntersection.IntersectRect( &rcTLP, &rcWndOld ) ) pWndTLP->UpdateWindow(); } // if( !rcTLP.IsRectEmpty() ) } // if( pWndTLP->IsWindowVisible() ) } // if( pWndTLP != NULL ) } // if( !rcWndOld.IsRectEmpty() ) _FreeWinObjects(); ASSERT( ::IsWindow(GetSafeHwnd()) ); ASSERT( ( GetSite().GetAnimated() == NULL ) ); m_bAnimFinished = false; m_AnimationType = __AT_CONTENT_DISPLAY; // adjust screen position CRect rcWnd = _CalcTrackRect(); if( m_rgnWnd.GetSafeHandle() != NULL ) { ASSERT( m_bExcludeAreaSpec ); ASSERT( m_bCombineWithEA ); ASSERT( m_eCombineAlign != __CMBA_NONE ); CRgn rgnTmp; VERIFY( rgnTmp.CreateRectRgn(0,0,0,0) ); rgnTmp.CopyRgn( &m_rgnWnd ); ASSERT( rgnTmp.GetSafeHandle() != NULL ); VERIFY( SetWindowRgn( (HRGN)rgnTmp.Detach(), FALSE ) ); } // if( m_rgnWnd.GetSafeHandle() != NULL ) m_bAnimFinished = true; m_ePlaySoundOnAnimationFinished = CExtSoundPlayer::__ON_MENU_EXPAND_CLICKED; m_AnimationType = g_bMenuExpandAnimation ? __AT_CONTENT_EXPAND : __AT_CONTENT_DISPLAY ; _StartAnimation(); if( m_AnimationType == __AT_NONE ) { m_AnimationType = __AT_CONTENT_DISPLAY; _StartAnimation(); ASSERT( m_AnimationType == __AT_CONTENT_DISPLAY ); } if( m_bScrollingAvailable ) _RecalcLayoutImpl(); SetWindowPos( NULL, rcWnd.left, rcWnd.top, rcWnd.Width(), rcWnd.Height(), SWP_NOACTIVATE |SWP_SHOWWINDOW //|SWP_NOREDRAW //|SWP_NOSENDCHANGING |SWP_NOZORDER //|SWP_NOOWNERZORDER //|SWP_NOCOPYBITS ); ASSERT( IsWindowVisible() ); } // if size of all items was changed else UpdateWindow(); ASSERT( m_hWndCmdReciever != NULL ); ASSERT( ::IsWindow(m_hWndCmdReciever) ); ::SendMessage( m_hWndCmdReciever, g_nMsgNotifyMenuExpanded, 0, LPARAM( this ) ); } bool CExtPopupMenuWnd::IsAllItemsRarelyUsed() const { ASSERT_VALID( this ); INT _iter = 0; for( ; _iter < m_items_all.GetSize(); ++_iter ) { const MENUITEMDATA & mi = m_items_all[ _iter ]; if( mi.IsDisplayed() || mi.IsExtraMark() ) return false; } // for( ; _iter != m_items_all.end(); ++_iter ) return true; } void CExtPopupMenuWnd::_SyncItems() { ASSERT_VALID( this ); ASSERT( m_hWndCmdReciever != NULL ); ASSERT( ::IsWindow(m_hWndCmdReciever) ); INT nIconAreaWidthLager = (__EXT_MENU_ICON_CX+__EXT_MENU_GAP*2); for( INT _iter = 0; _iter < m_items_all.GetSize(); ++_iter ) { MENUITEMDATA & mi = m_items_all[ _iter ]; int nWidth = mi.GetIconAreaWidth(); nIconAreaWidthLager = max( nIconAreaWidthLager, nWidth ); } // for( INT _iter = 0; _iter < m_items_all.GetSize(); ++_iter ) for( _iter = 0; _iter < m_items_all.GetSize(); ++_iter ) { MENUITEMDATA & mi = m_items_all[ _iter ]; mi.UpdateIconAreaWidth( nIconAreaWidthLager ); } // for( _iter = 0; _iter < m_items_all.GetSize(); ++_iter ) m_bExpandAvailable = false; m_sizeFullItems.cx = m_sizeFullItems.cy = 1; int nItemIndex = 0; INT _iterLast = m_items_all.GetSize(); INT _iterLastVisSep = _iterLast; bool bAtLeastOneDisplayed = false; for( _iter = 0; _iter < m_items_all.GetSize(); ++_iter ) { MENUITEMDATA & mi = m_items_all[ _iter ]; mi.SetIndex( nItemIndex++ ); if( m_bExpandWasPressed ) { mi.SetDisplayed( true ); } // if( m_bExpandWasPressed ) else { if( mi.IsPopup() ) { // if popup sub-menu ASSERT( mi.GetPopup() != NULL ); mi.GetPopup()->_SyncItems(); CExtCmdItem * pCmdItem = mi.GetCmd(); if( pCmdItem != NULL ) { bool bRarelyUsed = ( (!_FindCustomizeMode()) && pCmdItem->StateIsRarelyUsed() ) ? true : false; if( bRarelyUsed ) { _iterLast = m_items_all.GetSize(); mi.SetDisplayed( false ); } else { _iterLast = _iter; _iterLastVisSep = m_items_all.GetSize(); mi.SetDisplayed( true ); } } // if( pCmdItem != NULL ) else if( mi.IsAllItemsRarelyUsed() ) { // if all not displayed _iterLast = m_items_all.GetSize(); mi.SetDisplayed( false ); } // if all not displayed else { // if at least one displayed _iterLast = _iter; _iterLastVisSep = m_items_all.GetSize(); mi.SetDisplayed( true ); } // if at least one displayed } // if popup sub-menu else { // if separator or command item if( mi.IsSeparator() ) { // if separator if( _iterLast != m_items_all.GetSize() || ( _iterLast == m_items_all.GetSize() && (_iterLastVisSep == m_items_all.GetSize()) && bAtLeastOneDisplayed ) ) { _iterLastVisSep = _iter; mi.SetDisplayed( true ); } else { _iterLast = m_items_all.GetSize(); mi.SetDisplayed( false ); } } // if separator else { // if command item CExtCmdItem * pCmdItem = mi.GetCmd(); if( pCmdItem == NULL || mi.IsExtraMark() ) { _iterLast = m_items_all.GetSize(); mi.SetDisplayed( true ); } else if( pCmdItem->StateIsRarelyUsed() ) { // if command rarely used _iterLast = m_items_all.GetSize(); mi.SetDisplayed( false ); } // if command rarely used else { // if basic command or frequently used _iterLast = _iter; _iterLastVisSep = m_items_all.GetSize(); mi.SetDisplayed( true ); } // if basic command or frequently used } // if command item } // if separator or command item } // else from if( m_bExpandWasPressed ) if( mi.IsDisplayed() ) { bAtLeastOneDisplayed = true; m_sizeFullItems.cy += mi.GetMeasuredHeight(); if( m_sizeFullItems.cx < mi.GetMeasuredWidth() ) m_sizeFullItems.cx = mi.GetMeasuredWidth(); } // if( mi.IsDisplayed() ) else { ASSERT( !m_bExpandWasPressed ); m_bExpandAvailable = true; } // else from if( mi.IsDisplayed() ) } // for( _iter = 0; _iter < m_items_all.GetSize(); ++_iter ) if( _iterLastVisSep != m_items_all.GetSize() ) { // remove last separator if( _iterLastVisSep >= _iterLast || _iterLast == m_items_all.GetSize() ) { m_items_all[_iterLastVisSep].SetDisplayed( false ); m_sizeFullItems.cy -= m_items_all[_iterLastVisSep].GetMeasuredHeight(); } } // remove last separator static const INT nMixDx = 80; if( m_sizeFullItems.cx < nMixDx ) m_sizeFullItems.cx = nMixDx; } const CExtPopupMenuWnd * CExtPopupMenuWnd::ItemGetPopup( INT nPos ) const { ASSERT_VALID( this ); ASSERT( GetTrackingMenu() != this ); INT nCountOfItems = ItemGetCount(); if( nPos < 0 || nPos >= nCountOfItems ) { ASSERT( FALSE ); return NULL; } const MENUITEMDATA & mi = _GetItemRef(nPos); /* UINT nCmdID = mi.GetCmdID(); if( nCmdID != TYPE_POPUP ) return NULL; ASSERT( mi.IsPopup() ); */ if( !mi.IsPopup() ) return NULL; return mi.GetPopup(); } BOOL CExtPopupMenuWnd::ItemRemove( INT nPos // = -1 // remove all ) { ASSERT_VALID( this ); ASSERT( GetTrackingMenu() != this ); if( nPos < 0 ) { if( !_BuildItems( NULL, false ) ) { ASSERT( FALSE ); return FALSE; } _SyncItems(); return TRUE; } // if( nPos < 0 ) INT nCountOfItems = ItemGetCount(); if( nPos >= nCountOfItems ) { ASSERT( FALSE ); return FALSE; } MENUITEMDATA & mi = _GetItemRef(nPos); if( mi.IsPopup() ) { mi.GetPopup()->_OnCancelMode(); VERIFY( mi.GetPopup()->_BuildItems( NULL, false ) ); mi.DestroyPopup(); } m_items_all.RemoveAt( nPos ); ASSERT( nCountOfItems == m_items_all.GetSize() + 1 ); m_nCurIndex = -1; _SyncItems(); return TRUE; } BOOL CExtPopupMenuWnd::ItemInsertSpecPopup( // insert specific popup implementation CExtPopupMenuWnd * pSpecPopup, INT nPos, // = -1 // append __EXT_MFC_SAFE_LPCTSTR sText, // = NULL HICON hIcon // = NULL ) { ASSERT_VALID( this ); ASSERT( pSpecPopup != NULL ); INT nCountOfMenuItems = ItemGetCount(); if( nPos < 0 ) nPos = nCountOfMenuItems; if( nPos > nCountOfMenuItems ) { ASSERT( FALSE ); return FALSE; } ASSERT( m_hWndCmdReciever != NULL ); ASSERT( ::IsWindow(m_hWndCmdReciever) ); MENUITEMDATA mi; mi.SetCmdReciever( m_hWndCmdReciever ); pSpecPopup->m_bTopLevel = false; mi.SetPopup( nPos, sText, hIcon, pSpecPopup ); ASSERT( mi.GetPopup()->m_pWndParentMenu == NULL ); // still not initialized ASSERT( !mi.GetPopup()->m_bTopLevel ); mi.GetPopup()->m_pWndParentMenu = this; mi.SetDisplayed( true ); _InsertItem( nPos, mi ); if( m_bTopLevel ) _SyncItems(); else { ASSERT( m_pWndParentMenu != NULL ); m_pWndParentMenu->_SyncItems(); } return TRUE; } BOOL CExtPopupMenuWnd::ItemInsert( UINT nCmdID, // = TYPE_SEPARATOR, INT nPos, // = -1 // append __EXT_MFC_SAFE_LPCTSTR sText, // = NULL // for TYPE_POPUP only HICON hIcon, // = NULL // for TYPE_POPUP only HWND hWndSpecCmdReciever // = NULL // specific command reciever ) { ASSERT_VALID( this ); ASSERT( GetTrackingMenu() != this ); INT nCountOfMenuItems = ItemGetCount(); if( nPos < 0 ) nPos = nCountOfMenuItems; if( nPos > nCountOfMenuItems ) { ASSERT( FALSE ); return FALSE; } ASSERT( m_hWndCmdReciever != NULL ); ASSERT( ::IsWindow(m_hWndCmdReciever) ); MENUITEMDATA mi; mi.SetCmdReciever( (hWndSpecCmdReciever != NULL) ? hWndSpecCmdReciever : m_hWndCmdReciever ); switch( nCmdID ) { case TYPE_POPUP: mi.SetPopup( nPos, sText, hIcon ); break; // case TYPE_POPUP case TYPE_SEPARATOR: mi.SetSeparator( nPos ); break; // case TYPE_SEPARATOR default: { ASSERT( m_hWndCmdReciever != NULL ); ASSERT( ::IsWindow(m_hWndCmdReciever) ); CExtCmdItem * pCmdItem = g_CmdManager->CmdGetPtr( g_CmdManager->ProfileNameFromWnd( (hWndSpecCmdReciever != NULL) ? hWndSpecCmdReciever : m_hWndCmdReciever ), nCmdID ); ASSERT( pCmdItem != NULL ); if( pCmdItem == NULL ) return FALSE; VERIFY( mi.UpdateCmdManagerCommand( pCmdItem, nPos ) ); } break; // default } // switch( nCmdID ) if( mi.IsPopup() ) { ASSERT( mi.GetPopup()->m_pWndParentMenu == NULL ); // still not initialized mi.GetPopup()->m_pWndParentMenu = this; ASSERT( !mi.GetPopup()->m_bTopLevel ); } _InsertItem( nPos, mi ); if( m_bTopLevel ) _SyncItems(); else { //ASSERT( m_pWndParentMenu != NULL ); //m_pWndParentMenu->_SyncItems(); if( m_pWndParentMenu != NULL ) m_pWndParentMenu->_SyncItems(); } return TRUE; } BOOL CExtPopupMenuWnd::ItemInsertCommand( // no references to command manager UINT nCmdID, // = TYPE_SEPARATOR INT nPos, // = -1 // append __EXT_MFC_SAFE_LPCTSTR sItemText, // = NULL __EXT_MFC_SAFE_LPCTSTR sAccelText, // = NULL HICON hIcon, // = NULL bool bCopyIcon, // = true int nCheck, // = 0 // 0 - no check, 1 - checked, 2 - indeterminate, 3 - radio HWND hWndSpecCmdReciever // = NULL ) { CExtCmdIcon icon; if( hIcon != NULL ) icon.AssignFromHICON( hIcon, bCopyIcon ); BOOL bRetVal = ItemInsertCommand( nCmdID, nPos, sItemText, sAccelText, icon, nCheck, hWndSpecCmdReciever ); return bRetVal; } BOOL CExtPopupMenuWnd::ItemInsertCommand( // no references to command manager UINT nCmdID, INT nPos, // -1 append __EXT_MFC_SAFE_LPCTSTR sItemText, // may be NULL __EXT_MFC_SAFE_LPCTSTR sAccelText, // may be NULL const CExtCmdIcon & icon, int nCheck, // = 0 // 0 - no check, 1 - checked, 2 - indeterminate, 3 - radio HWND hWndSpecCmdReciever // = NULL ) { ASSERT_VALID( this ); ASSERT( GetTrackingMenu() != this ); INT nCountOfMenuItems = ItemGetCount(); if( nPos < 0 ) nPos = nCountOfMenuItems; if( nPos > nCountOfMenuItems ) { ASSERT( FALSE ); return FALSE; } ASSERT( m_hWndCmdReciever != NULL ); ASSERT( ::IsWindow(m_hWndCmdReciever) ); MENUITEMDATA mi; mi.SetCmdReciever( (hWndSpecCmdReciever != NULL) ? hWndSpecCmdReciever : m_hWndCmdReciever ); mi.SetNoCmdUI( true ); switch( nCmdID ) { case TYPE_POPUP: mi.SetPopup( nPos, (sItemText == NULL) ? _T("") : sItemText, NULL ); mi.SetPopupIcon( icon ); break; // case TYPE_POPUP case TYPE_SEPARATOR: mi.SetSeparator( nPos ); break; // case TYPE_SEPARATOR default: { ASSERT( m_hWndCmdReciever != NULL ); ASSERT( ::IsWindow(m_hWndCmdReciever) ); mi.SetCmdID( nCmdID ); mi.SetText( (sItemText == NULL) ? _T("") : sItemText ); mi.SetAccelText( (sAccelText == NULL) ? _T("") : sAccelText ); mi.AccelCharInit(); mi.SetPopupIcon( icon ); switch( nCheck ) { case 1: mi.Check( true ); break; case 2: mi.Indeterminate( true ); break; case 3: mi.Radio( true ); break; } // switch( nCheck ) mi.MeasureItem(); } break; // default } // switch( nCmdID ) mi.SetIndex( nPos ); mi.SetDisplayed( true ); if( mi.IsPopup() ) { ASSERT( mi.GetPopup()->m_pWndParentMenu == NULL ); // still not initialized mi.GetPopup()->m_pWndParentMenu = this; ASSERT( !mi.GetPopup()->m_bTopLevel ); } _InsertItem( nPos, mi ); if( m_bTopLevel ) _SyncItems(); else { //ASSERT( m_pWndParentMenu != NULL ); //m_pWndParentMenu->_SyncItems(); if( m_pWndParentMenu != NULL ) m_pWndParentMenu->_SyncItems(); } return TRUE; } void CExtPopupMenuWnd::SetLeftAreaWidth( UINT nWidth // = 0 ) { m_nLeftAreaWidth = nWidth; } UINT CExtPopupMenuWnd::GetLeftAreaWidth() const { return m_nLeftAreaWidth; } BOOL CExtPopupMenuWnd::CreatePopupMenu( HWND hWndCmdRecv ) { ASSERT_VALID( this ); ASSERT( ::IsWindow(hWndCmdRecv) ); ASSERT( GetTrackingMenu() != this ); if( m_bTopLevel || m_pWndParentMenu != NULL || ItemGetCount() != 0 ) { // already created ASSERT( FALSE ); return FALSE; } m_sizeFullItems.cx = m_sizeFullItems.cy = 1; m_bTopLevel = true; m_pWndParentMenu = NULL; m_hWndCmdReciever = hWndCmdRecv; return TRUE; } void CExtPopupMenuWnd::SetCmdTargetToAllItems( HWND hWndSpecCmdReciever, // = NULL bool bOnlyThisLevel // = false ) { ASSERT_VALID( this ); ASSERT( GetTrackingMenu() != this ); INT iter = 0; for( ; iter < m_items_all.GetSize(); iter++) { MENUITEMDATA & mi = m_items_all[ iter ]; if( mi.IsSeparator() ) continue; if( mi.IsPopup() ) { if( !bOnlyThisLevel ) mi.GetPopup()->SetCmdTargetToAllItems( hWndSpecCmdReciever, true ); } else { mi.SetCmdReciever( hWndSpecCmdReciever ); } } } //CExtPopupMenuWnd::const_items_container_t & // CExtPopupMenuWnd::_GetItemsContaner() const //{ // return m_items_all; //} // //CExtPopupMenuWnd::items_container_t & // CExtPopupMenuWnd::_GetItemsContaner() //{ // return m_items_all; //} CExtPopupMenuWnd::MENUITEMDATA & CExtPopupMenuWnd::_GetItemRef(int nIndex) { ASSERT_VALID( this ); ASSERT( nIndex >= 0 && nIndex < m_items_all.GetSize() ); MENUITEMDATA & mi = m_items_all[nIndex]; return mi; } const CExtPopupMenuWnd::MENUITEMDATA & CExtPopupMenuWnd::_GetItemRef(int nIndex) const { ASSERT_VALID( this ); return (const_cast< CExtPopupMenuWnd * > (this)) -> _GetItemRef(nIndex); } void CExtPopupMenuWnd::_InsertItem( int nInsertBefore, MENUITEMDATA & mi ) { ASSERT_VALID( this ); m_items_all.InsertAt( (nInsertBefore < 0) ? m_items_all.GetSize() : nInsertBefore , mi ); } bool CExtPopupBaseWnd::_IsPopupWithShadows() const { if( ! CExtPopupMenuWnd::g_bMenuWithShadows ) return false; return true; } bool CExtPopupMenuWnd::_IsPopupWithShadows() const { if( ! CExtPopupBaseWnd::_IsPopupWithShadows() ) return false; if( m_dwTrackFlags & TPMX_NO_SHADOWS ) return false; return true; } int CExtPopupBaseWnd::_GetPopupShadowSize() const { if( !_IsPopupWithShadows() ) return 0; //int nBitsPerPixel = CExtPaintManager::stat_GetBPP(); // if( nBitsPerPixel <= 8 ) // return 0; return g_PaintManager->GetMenuShadowSize(); }; int CExtPopupMenuWnd::_GetPopupShadowSize() const { return CExtPopupBaseWnd::_GetPopupShadowSize(); } #if (!defined __EXT_MFC_NO_CUSTOMIZE) void CExtPopupMenuWnd::_SetDropIndexBefore( int nIndex // = -1 // reset ) { ASSERT_VALID( this ); if( m_nHelperDropIndexBefore == nIndex ) return; m_nHelperDropIndexBefore = nIndex; if( GetSafeHwnd() == NULL || (! ::IsWindow(GetSafeHwnd()) ) ) return; CClientDC dc( this ); _DoPaint( dc ); } // CExtCustomizeSite::ICustomizeDropTarget DROPEFFECT CExtPopupMenuWnd::OnCustomizeTargetOver( CExtCustomizeSite::CCmdDragInfo & _dragInfo, CPoint point, DWORD dwKeyState ) { ASSERT_VALID( this ); ASSERT( !_dragInfo.IsEmpty() ); dwKeyState; point; if( m_pDragSrcNode != NULL ) m_bHelperDragOverPassed = true; ASSERT_VALID( m_pNode ); ASSERT_VALID( _dragInfo.m_pDropNodeC ); if( m_pNode == _dragInfo.m_pDropNodeC || _dragInfo.m_pDropNodeC->IsChild( m_pNode ) ) return DROPEFFECT_NONE; // _DoResetChainPositions(); if( ItemGetCount() == 0 ) { if( (dwKeyState & MK_CONTROL) != NULL ) return DROPEFFECT_COPY; return DROPEFFECT_MOVE; } int nIndex = _HitTest( point ); if( nIndex < 0 ) { if( nIndex == IDX_SCROLL_TOP || nIndex == IDX_SCROLL_BOTTOM ) _StartScrolling( nIndex ); _SetDropIndexBefore(); //_ItemFocusCancel( TRUE ); return DROPEFFECT_NONE; } MENUITEMDATA & miPreTest = CExtPopupMenuWnd::_GetItemRef( nIndex ); if( miPreTest.IsSeparator() ) { if( nIndex == 0 ) { ASSERT( FALSE ); _SetDropIndexBefore(); _ItemFocusCancel( TRUE ); return DROPEFFECT_NONE; } // if( nIndex == 0 ) nIndex--; } // if( miPreTest.IsSeparator() ) MENUITEMDATA & mi = CExtPopupMenuWnd::_GetItemRef( nIndex ); if( mi.IsSeparator() ) { ASSERT( FALSE ); _SetDropIndexBefore(); _ItemFocusCancel( TRUE ); return DROPEFFECT_NONE; } // if( mi.IsSeparator() ) CRect rcItem; _GetItemRect( nIndex, rcItem ); int nMidY = rcItem.CenterPoint().y; if( point.y > nMidY ) nIndex++; _SetDropIndexBefore( nIndex ); if( mi.IsPopup() ) _ItemFocusSet( mi.GetIndex(), TRUE, TRUE, FALSE ); else _ItemFocusCancel( TRUE ); if( (dwKeyState & MK_CONTROL) != NULL ) return DROPEFFECT_COPY; return DROPEFFECT_MOVE; } void CExtPopupMenuWnd::OnCustomizeTargetLeave() { ASSERT_VALID( this ); _SetDropIndexBefore(); } bool CExtPopupMenuWnd::OnCustomizeTargetDrop( CExtCustomizeSite::CCmdDragInfo & _dragInfo, CPoint point, DROPEFFECT de ) { ASSERT_VALID( this ); ASSERT( !_dragInfo.IsEmpty() ); _dragInfo; point; ASSERT( de == DROPEFFECT_NONE || de == DROPEFFECT_MOVE || de == DROPEFFECT_COPY ); int nItemCount = ItemGetCount(); if( de == DROPEFFECT_NONE || ( nItemCount > 0 && m_nHelperDropIndexBefore < 0 ) ) { _SetDropIndexBefore(); m_ptHelperDragStart.x = m_ptHelperDragStart.y = 0; return false; } CExtCustomizeSite * pSite = _FindCustomizeSite(); ASSERT( pSite != NULL ); ASSERT_VALID( m_pNode ); ASSERT_VALID( _dragInfo.m_pDropNodeC ); bool bRetVal = true; m_bHelperNoHideChild = true; int nNodeInsertPos = -1; CExtCustomizeCmdTreeNode * pClonedNode = _dragInfo.m_pDropNodeC->CloneNode( pSite ); ASSERT_VALID( pClonedNode ); if( _dragInfo.m_pDropNodeI != NULL ) { ASSERT_VALID( _dragInfo.m_pDropNodeI ); // reset basic command ID pClonedNode->SetCmdID( _dragInfo.m_pDropNodeI->GetCmdID( false ), false ); pClonedNode->SetCmdID( _dragInfo.m_pDropNodeC->GetCmdID( true ), true ); } // if( _dragInfo.m_pDropNodeI != NULL ) if( nItemCount == 0 ) { nNodeInsertPos = 0; pClonedNode->ModifyFlags( 0, __ECTN_GROUP_START ); } // if( nItemCount == 0 ) else { ASSERT( m_nHelperDropIndexBefore >= 0 && m_nHelperDropIndexBefore <= nItemCount ); if( m_nHelperDropIndexBefore == nItemCount ) { nNodeInsertPos = m_pNode->GetNodeCount(); } // if( m_nHelperDropIndexBefore == nItemCount ) else { if( m_nHelperDropIndexBefore == 0 ) pClonedNode->ModifyFlags( 0, __ECTN_GROUP_START ); MENUITEMDATA & miDropPos = _GetItemRef( m_nHelperDropIndexBefore ); CExtCustomizeCmdTreeNode * pDropBeforeNode = miDropPos.IsSeparator() ? ( _GetItemRef( m_nHelperDropIndexBefore + 1 ).GetCmdNode() ) : ( miDropPos.GetCmdNode() ) ; ASSERT_VALID( pDropBeforeNode ); nNodeInsertPos = pDropBeforeNode->GetOwnIndex(); if( (pDropBeforeNode->GetFlags() & __ECTN_GROUP_START) != 0 ) { ASSERT( m_nHelperDropIndexBefore > 0 ); pClonedNode->ModifyFlags( __ECTN_GROUP_START, 0 ); pDropBeforeNode->ModifyFlags( 0, __ECTN_GROUP_START ); } // if( (pDropBeforeNode->GetFlags() & __ECTN_GROUP_START) != 0 ) else { } // else from if( (pDropBeforeNode->GetFlags() & __ECTN_GROUP_START) != 0 ) if( m_pDragSrcNode != NULL ) { ASSERT( 0 <= m_nDragSrcIdx && m_nDragSrcIdx < nItemCount ); if( pDropBeforeNode == m_pDragSrcNode ) { delete pClonedNode; _SetDropIndexBefore(); ASSERT( m_nDragSrcIdx >= 0 && m_nDragSrcIdx < nItemCount ); _ItemFocusSet( m_nDragSrcIdx, TRUE, TRUE, FALSE ); m_bHelperNoHideChild = true; CClientDC dc( this ); _DoPaint( dc ); m_bHelperNoRemoveSrc = true; return true; } // if( pDropBeforeNode == m_pDragSrcNode ) int nDragNodeIdx = m_pDragSrcNode->GetOwnIndex(); if( nDragNodeIdx > 0 ) { CExtCustomizeCmdTreeNode * pDragNodePr = m_pDragSrcNode->GetParentNode()->ElementAt( nDragNodeIdx-1 ); ASSERT_VALID( pDragNodePr ); if( pDragNodePr == m_pDragSrcNode ) { delete pClonedNode; _SetDropIndexBefore(); ASSERT( m_nDragSrcIdx >= 0 && m_nDragSrcIdx < nItemCount ); _ItemFocusSet( m_nDragSrcIdx, TRUE, TRUE, FALSE ); m_bHelperNoHideChild = true; CClientDC dc( this ); _DoPaint( dc ); m_bHelperNoRemoveSrc = true; return true; } // if( pDragNodePr == m_pDragSrcNode ) } // if( nDragNodeIdx > 0 ) } // if( m_pDragSrcNode != NULL ) } // else from if( m_nHelperDropIndexBefore == nItemCount ) } // else from if( nItemCount == 0 ) _ItemFocusCancel( TRUE ); ASSERT( 0 <= nNodeInsertPos && nNodeInsertPos <= m_pNode->GetNodeCount() ); m_pNode->InsertNode( pSite, pClonedNode, nNodeInsertPos ); MENUITEMDATA mi; mi.SetCmdReciever( m_hWndCmdReciever ); VERIFY( mi.UpdateFromCmdTree( m_hWndCmdReciever, pClonedNode, m_nHelperDropIndexBefore ) ); if( mi.IsPopup() ) { mi.GetPopup()->m_hWndCmdReciever = m_hWndCmdReciever; mi.GetPopup()->UpdateFromCmdTree( m_hWndCmdReciever, pClonedNode, false ); mi.GetPopup()->m_pWndParentMenu = this; } // if( mi.IsPopup() ) ASSERT( !mi.IsSeparator() ); ASSERT( ((LPVOID)mi.GetCmdNode()) == ((LPVOID)pClonedNode) ); _InsertItem( m_nHelperDropIndexBefore, mi ); _SyncItems(); ShowWindow( SW_HIDE ); _RecalcLayoutImpl(); VERIFY( SetWindowRgn( NULL, FALSE ) ); ASSERT( !IsWindowVisible() ); _FreeWinObjects(); // adjust screen position CRect rcWnd = _CalcTrackRect(); if( m_rgnWnd.GetSafeHandle() != NULL ) { ASSERT( m_bExcludeAreaSpec ); ASSERT( m_bCombineWithEA ); ASSERT( m_eCombineAlign != __CMBA_NONE ); CRgn rgnTmp; VERIFY( rgnTmp.CreateRectRgn(0,0,0,0) ); rgnTmp.CopyRgn( &m_rgnWnd ); ASSERT( rgnTmp.GetSafeHandle() != NULL ); VERIFY( SetWindowRgn( (HRGN)rgnTmp.Detach(), FALSE ) ); } // if( m_rgnWnd.GetSafeHandle() != NULL ) SetWindowPos( NULL, rcWnd.left, rcWnd.top, rcWnd.Width(), rcWnd.Height(), SWP_NOACTIVATE |SWP_NOZORDER //|SWP_NOOWNERZORDER ); if( m_bScrollingAvailable ) _RecalcLayoutImpl(); ShowWindow( SW_SHOWNA ); _SetDropIndexBefore(); m_ptHelperDragStart.x = m_ptHelperDragStart.y = 0; return bRetVal; } // CExtCustomizeSite::ICustomizeDropSource void CExtPopupMenuWnd::OnCustomizeSourceDragComplete( DROPEFFECT de, bool bCanceled, bool * p_bNoResetActiveItem ) { ASSERT_VALID( this ); ASSERT( de == DROPEFFECT_NONE || de == DROPEFFECT_MOVE || de == DROPEFFECT_COPY ); ASSERT( p_bNoResetActiveItem != NULL ); // if( m_ptHelperDragStart.y != 0 // && m_bHelperNoHideChild // && de != DROPEFFECT_NONE // ) // { // m_ptHelperDragStart.x = m_ptHelperDragStart.y = 0; // return; // } m_ptHelperDragStart.x = m_ptHelperDragStart.y = 0; if( GetSafeHwnd() != NULL && (!m_bHelperNoHideChild) ) _ItemFocusCancel( TRUE ); m_bHelperNoHideChild = false; CExtCustomizeSite * pSite = _FindCustomizeSite(); ASSERT( pSite != NULL ); if( (!m_bHelperDragOverPassed) && m_pDragSrcNode != NULL ) m_bHelperNoRemoveSrc = true; if( bCanceled || m_bHelperNoRemoveSrc || de == DROPEFFECT_COPY ) { m_bHelperNoRemoveSrc = false; if( pSite->IsCustomizeMode() ) *p_bNoResetActiveItem = true; return; } // if( bCanceled || de == DROPEFFECT_COPY || m_bHelperAddRemSeparator ) CExtCustomizeCmdTreeNode * pNode = pSite->DraggedNodeGet(); ASSERT_VALID( pNode ); ASSERT_VALID( m_pNode ); ASSERT( ((LPVOID)pNode->GetParentNode()) == ((LPVOID)m_pNode) ); int nItemCount = ItemGetCount(); bool bPrevSeparator = false; for( int nItem = 0; nItem < nItemCount; nItem++ ) { MENUITEMDATA & mi = _GetItemRef( nItem ); if( mi.IsSeparator() ) { ASSERT( !bPrevSeparator ); bPrevSeparator = true; continue; } CExtCustomizeCmdTreeNode * pCurrNode = mi.GetCmdNode(); ASSERT_VALID( pCurrNode ); if( ((LPVOID)pCurrNode) == ((LPVOID)pNode) ) break; bPrevSeparator = false; } // for( int nItem = 0; nItem < nItemCount; nItem++ ) ASSERT( nItem < nItemCount ); // should be found if( bPrevSeparator ) { // ASSERT( (pNode->GetFlags() & __ECTN_GROUP_START) != 0 ); pNode->ModifyFlags( __ECTN_GROUP_START, 0 ); ASSERT( nItem > 0 ); MENUITEMDATA & miRemove = _GetItemRef( nItem-1 ); ASSERT( miRemove.IsSeparator() ); pNode->ModifyFlags( 0, __ECTN_GROUP_START ); // if( miRemove.IsPopup() ) // miRemove.DestroyPopup(); m_items_all.RemoveAt( nItem-1, 2 ); m_nCurIndex = -1; nItemCount -= 2; } // if( bPrevSeparator ) else { // ASSERT( (pNode->GetFlags() & __ECTN_GROUP_START) == 0 ); pNode->ModifyFlags( 0, __ECTN_GROUP_START ); MENUITEMDATA & miRemove = _GetItemRef( nItem ); if( miRemove.IsPopup() ) miRemove.DestroyPopup(); m_items_all.RemoveAt( nItem, 1 ); m_nCurIndex = -1; nItemCount--; } // else from if( bPrevSeparator ) CExtCmdItem * pCmdItem = g_CmdManager->CmdGetPtr( g_CmdManager->ProfileNameFromWnd(m_hWnd), pNode->GetCmdID( false ) ); ASSERT( pCmdItem != NULL ); pNode->RemoveSelf( pCmdItem ); pSite->DraggedNodeSet( NULL ); if( nItemCount > 0 && _GetItemRef(0).IsSeparator() ) { m_items_all.RemoveAt( 0, 1 ); m_nCurIndex = -1; m_pNode->ElementAt(0)->ModifyFlags( 0, __ECTN_GROUP_START ); nItemCount--; } // if( nItemCount > 0 ... if( nItemCount > 0 && _GetItemRef(nItemCount-1).IsSeparator() ) { m_items_all.RemoveAt( nItemCount-1, 1 ); m_nCurIndex = -1; nItemCount--; } // if( nItemCount > 0 ... _SyncItems(); _SetDropIndexBefore(); if( m_hWnd == NULL || (! ::IsWindow(m_hWnd) ) ) return; ShowWindow( SW_HIDE ); _RecalcLayoutImpl(); VERIFY( SetWindowRgn( NULL, FALSE ) ); ASSERT( !IsWindowVisible() ); _FreeWinObjects(); // adjust screen position CRect rcWnd = _CalcTrackRect(); if( m_rgnWnd.GetSafeHandle() != NULL ) { ASSERT( m_bExcludeAreaSpec ); ASSERT( m_bCombineWithEA ); ASSERT( m_eCombineAlign != __CMBA_NONE ); CRgn rgnTmp; VERIFY( rgnTmp.CreateRectRgn(0,0,0,0) ); rgnTmp.CopyRgn( &m_rgnWnd ); ASSERT( rgnTmp.GetSafeHandle() != NULL ); VERIFY( SetWindowRgn( (HRGN)rgnTmp.Detach(), FALSE ) ); } // if( m_rgnWnd.GetSafeHandle() != NULL ) SetWindowPos( NULL, rcWnd.left, rcWnd.top, rcWnd.Width(), rcWnd.Height(), SWP_NOACTIVATE |SWP_NOZORDER //|SWP_NOOWNERZORDER ); if( m_bScrollingAvailable ) _RecalcLayoutImpl(); ShowWindow( SW_SHOWNA ); } #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) ///////////////////////////////////////////////////////////////////////////// // CExtPopupColorMenuWnd IMPLEMENT_DYNCREATE(CExtPopupColorMenuWnd, CExtPopupMenuWnd) BEGIN_MESSAGE_MAP(CExtPopupColorMenuWnd, CExtPopupMenuWnd) //{{AFX_MSG_MAP(CExtPopupColorMenuWnd) //}}AFX_MSG_MAP ON_WM_QUERYNEWPALETTE() ON_WM_PALETTECHANGED() END_MESSAGE_MAP() UINT CExtPopupColorMenuWnd::g_nMsgNotifyColorChanged = ::RegisterWindowMessage( _T("CExtPopupColorMenuWnd::g_nMsgNotifyColorChanged") ); UINT CExtPopupColorMenuWnd::g_nMsgNotifyColorChangedFinally = ::RegisterWindowMessage( _T("CExtPopupColorMenuWnd::g_nMsgNotifyColorChangedFinally") ); UINT CExtPopupColorMenuWnd::g_nMsgNotifyCustColor = ::RegisterWindowMessage( _T("CExtPopupColorMenuWnd::g_nMsgNotifyCustColor") ); #define __NCLR_DX 8 #define __NCLR_DY 5 #define __NCLR_COUNT (__NCLR_DX*__NCLR_DY) #define __NCLR_BOX_DX_SIZE 16 #define __NCLR_BOX_DY_SIZE 16 #define __NCLR_BOX_DX_SPACE 2 #define __NCLR_BOX_DY_SPACE 2 // table captured from color picker // control source by Chris Maunder CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY CExtPopupColorMenuWnd::g_colors[] = { CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0x00, 0x00, 0x00), _T("Black") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0xA5, 0x2A, 0x00), _T("Brown") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0x00, 0x40, 0x40), _T("Dark Olive Green") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0x00, 0x55, 0x00), _T("Dark Green") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0x00, 0x00, 0x5E), _T("Dark Teal") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0x00, 0x00, 0x8B), _T("Dark blue") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0x4B, 0x00, 0x82), _T("Indigo") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0x28, 0x28, 0x28), _T("Dark grey") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0x8B, 0x00, 0x00), _T("Dark red") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0xFF, 0x68, 0x20), _T("Orange") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0x8B, 0x8B, 0x00), _T("Dark yellow") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0x00, 0x93, 0x00), _T("Green") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0x38, 0x8E, 0x8E), _T("Teal") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0x00, 0x00, 0xFF), _T("Blue") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0x7B, 0x7B, 0xC0), _T("Blue-grey") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0x66, 0x66, 0x66), _T("Grey - 40") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0xFF, 0x00, 0x00), _T("Red") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0xFF, 0xAD, 0x5B), _T("Light orange") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0x32, 0xCD, 0x32), _T("Lime") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0x3C, 0xB3, 0x71), _T("Sea green") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0x7F, 0xFF, 0xD4), _T("Aqua") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0x7D, 0x9E, 0xC0), _T("Light blue") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0x80, 0x00, 0x80), _T("Violet") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0x7F, 0x7F, 0x7F), _T("Grey - 50") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0xFF, 0xC0, 0xCB), _T("Pink") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0xFF, 0xD7, 0x00), _T("Gold") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0xFF, 0xFF, 0x00), _T("Yellow") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0x00, 0xFF, 0x00), _T("Bright green") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0x40, 0xE0, 0xD0), _T("Turquoise") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0xC0, 0xFF, 0xFF), _T("Skyblue") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0x48, 0x00, 0x48), _T("Plum") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0xC0, 0xC0, 0xC0), _T("Light grey") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0xFF, 0xE4, 0xE1), _T("Rose") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0xD2, 0xB4, 0x8C), _T("Tan") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0xFF, 0xFF, 0xE0), _T("Light yellow") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0x98, 0xFB, 0x98), _T("Pale green ") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0xAF, 0xEE, 0xEE), _T("Pale turquoise") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0x68, 0x83, 0x8B), _T("Pale blue") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0xE6, 0xE6, 0xFA), _T("Lavender") ), CExtPopupColorMenuWnd::COLORREF_TABLE_ENTRY( RGB(0xFF, 0xFF, 0xFF), _T("White") ), }; CExtPopupColorMenuWnd::CExtPopupColorMenuWnd() { ASSERT( __NCLR_COUNT == sizeof(g_colors)/sizeof(COLORREF_TABLE_ENTRY) ); m_nColorIdxCurr = m_nInitialColorIdx = -1; m_hWndNotifyColorChanged = NULL; // - use command targed m_clrInitial = (COLORREF)(-1); // unexisting m_clrDefault = RGB(0,0,0); m_bEnableBtnColorDefault = true; m_bEnableBtnColorCustom = true; m_rcDefColorText.SetRectEmpty(); m_rcCustColorText.SetRectEmpty(); m_lParamCookie = 0; #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) CExtLocalResourceHelper _LRH; #endif // #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) if( !m_sBtnTextColorDefault.LoadString(IDS_COLOR_DEFAULT) ) { #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) ASSERT( FALSE ); #endif // #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) m_sBtnTextColorDefault = _T("Default Color"); } if( !m_sBtnTextColorCustom.LoadString(IDS_COLOR_CUSTOM) ) { #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) ASSERT( FALSE ); #endif // #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) m_sBtnTextColorCustom = _T("Custom Color ..."); } } BOOL CExtPopupColorMenuWnd::OnQueryNewPalette() { ASSERT_VALID( this ); Invalidate(); return CWnd::OnQueryNewPalette(); } void CExtPopupColorMenuWnd::OnPaletteChanged(CWnd* pFocusWnd) { ASSERT_VALID( this ); CWnd::OnPaletteChanged(pFocusWnd); if( pFocusWnd->GetSafeHwnd() != GetSafeHwnd() ) { Invalidate(); } } CSize CExtPopupColorMenuWnd::_CalcTrackSize() { ASSERT_VALID( this ); int nMenuBorderSize = g_PaintManager->GetMenuBorderSize(); int nMenuShadowSize = _GetPopupShadowSize(); CSize _size( (__NCLR_BOX_DX_SIZE + __NCLR_BOX_DX_SPACE*2) * __NCLR_DX + nMenuBorderSize*2 + nMenuShadowSize , (__NCLR_BOX_DY_SIZE + __NCLR_BOX_DY_SPACE*2) * __NCLR_DY + nMenuBorderSize*2 + nMenuShadowSize ); if( m_bEnableBtnColorDefault ) { _size.cy += __EXT_MENU_SEPARATOR_HEIGHT + __EXT_MENU_GAP*2; CExtSafeString sMeasureText( m_sBtnTextColorDefault ); sMeasureText.Replace( _T("&"), _T("") ); CWindowDC dc(NULL); CFont * pOldFont = dc.SelectObject( &(g_PaintManager->m_FontNormal) ); ASSERT( pOldFont != NULL ); CRect rect(0,0,0,0); CSize _sizeDefColorText; _sizeDefColorText.cy = DrawText( dc.GetSafeHdc(), sMeasureText, sMeasureText.GetLength(), &rect, DT_CALCRECT|DT_SINGLELINE |DT_LEFT|DT_VCENTER ); _sizeDefColorText.cx = rect.Width(); dc.SelectObject( pOldFont ); _sizeDefColorText.cx += __EXT_MENU_GAP * 2; if( _sizeDefColorText.cy < __EXT_MENU_MIN_HEIGHT ) _sizeDefColorText.cy = __EXT_MENU_MIN_HEIGHT; _size.cy += _sizeDefColorText.cy; if( _size.cx < _sizeDefColorText.cx ) _size.cx = _sizeDefColorText.cx; CPoint pt( nMenuBorderSize + __EXT_MENU_GAP , nMenuBorderSize + __EXT_MENU_GAP ); m_rcDefColorText.SetRect( pt, pt + CSize( max( _size.cx , _sizeDefColorText.cx ) - __EXT_MENU_GAP*2 - nMenuBorderSize*2 - nMenuShadowSize , _sizeDefColorText.cy ) ); } // if( m_bEnableBtnColorDefault ) if( m_bEnableBtnColorCustom ) { _size.cy += __EXT_MENU_SEPARATOR_HEIGHT + __EXT_MENU_GAP*2; CExtSafeString sMeasureText( m_sBtnTextColorCustom ); sMeasureText.Replace( _T("&"), _T("") ); CWindowDC dc(NULL); CFont * pOldFont = dc.SelectObject( &(g_PaintManager->m_FontNormal) ); ASSERT( pOldFont != NULL ); CRect rect(0,0,0,0); CSize _sizeCustColorText; _sizeCustColorText.cy = DrawText( dc.GetSafeHdc(), sMeasureText, sMeasureText.GetLength(), &rect, DT_CALCRECT|DT_SINGLELINE |DT_LEFT|DT_VCENTER ); _sizeCustColorText.cx = rect.Width(); dc.SelectObject( pOldFont ); _sizeCustColorText.cx += __EXT_MENU_GAP * 2; if( _sizeCustColorText.cy < __EXT_MENU_MIN_HEIGHT ) _sizeCustColorText.cy = __EXT_MENU_MIN_HEIGHT; _size.cy += _sizeCustColorText.cy; if( _size.cx < _sizeCustColorText.cx ) _size.cx = _sizeCustColorText.cx; CPoint pt( nMenuBorderSize + __EXT_MENU_GAP , nMenuBorderSize + __EXT_MENU_GAP ); m_rcCustColorText.SetRect( pt, pt + CSize( max( _size.cx , _sizeCustColorText.cx ) - __EXT_MENU_GAP*2 - nMenuBorderSize*2 - nMenuShadowSize , _sizeCustColorText.cy ) ); if( m_bEnableBtnColorDefault ) m_rcCustColorText.OffsetRect( 0, m_rcCustColorText.Height() + __EXT_MENU_GAP*2 + __EXT_MENU_SEPARATOR_HEIGHT ); m_rcCustColorText.OffsetRect( 0, nMenuBorderSize + (__NCLR_BOX_DY_SIZE + __NCLR_BOX_DY_SPACE*2) * __NCLR_DY + __NCLR_BOX_DY_SPACE ); } // if( m_bEnableBtnColorCustom ) _size.cx += m_nLeftAreaWidth; return _size; } CPoint CExtPopupColorMenuWnd::_GetColorItemCoord(int nIdx) { ASSERT_VALID( this ); ASSERT( nIdx >= 0 && nIdx < __NCLR_COUNT ); int nX = nIdx % __NCLR_DX; ASSERT( nX < __NCLR_DX ); int nY = nIdx / __NCLR_DX; ASSERT( nY < __NCLR_DY ); return CPoint(nX,nY); } CRect CExtPopupColorMenuWnd::_GetColorItemRect(int nIdx) { ASSERT_VALID( this ); ASSERT( nIdx >= 0 && nIdx < __NCLR_COUNT ); CPoint ptCoord = _GetColorItemCoord(nIdx); int nMenuBorderSize = g_PaintManager->GetMenuBorderSize(); CRect rcItem( CPoint( nMenuBorderSize + (__NCLR_BOX_DX_SIZE + __NCLR_BOX_DX_SPACE*2) * ptCoord.x + __NCLR_BOX_DX_SPACE , nMenuBorderSize + (__NCLR_BOX_DY_SIZE + __NCLR_BOX_DY_SPACE*2) * ptCoord.y + __NCLR_BOX_DY_SPACE ), CSize(__NCLR_BOX_DX_SIZE,__NCLR_BOX_DY_SIZE) ); if( m_bEnableBtnColorDefault ) { rcItem.OffsetRect( 0, m_rcDefColorText.Height() + __EXT_MENU_SEPARATOR_HEIGHT + __EXT_MENU_GAP*2 ); } CRect rcClient; _GetClientRect( &rcClient ); rcItem.OffsetRect( rcClient.TopLeft() ); rcItem.OffsetRect( m_nLeftAreaWidth, 0 ); return rcItem; } CRect CExtPopupColorMenuWnd::_CalcTrackRect() { ASSERT_VALID( this ); return CExtPopupMenuWnd::_CalcTrackRect(); } bool CExtPopupColorMenuWnd::_CreateHelper( CWnd * pWndCmdReciever ) { ASSERT_VALID( this ); if( !CExtPopupMenuWnd::_CreateHelper( pWndCmdReciever ) ) return false; int nIdx = _FindCellByColorRef(m_clrInitial); if( nIdx >= 0 ) { m_nInitialColorIdx = nIdx; Invalidate(); } CRect rcClient; _GetClientRect( &rcClient ); if( m_bEnableBtnColorDefault ) { m_rcDefColorText.OffsetRect( rcClient.TopLeft() ); m_rcDefColorText.OffsetRect( m_nLeftAreaWidth, 0 ); } if( m_bEnableBtnColorCustom ) { m_rcCustColorText.OffsetRect( rcClient.TopLeft() ); m_rcCustColorText.OffsetRect( m_nLeftAreaWidth, 0 ); } return true; } void CExtPopupColorMenuWnd::_DoPaint( CDC & dcPaint, bool bUseBackBuffer /*= true*/ ) { ASSERT_VALID( this ); ASSERT_VALID( (&dcPaint) ); ASSERT( dcPaint.GetSafeHdc() != NULL ); CRect rcRealClient; GetClientRect( &rcRealClient ); CRect rcClient; _GetClientRect( &rcClient ); // Select and realize the palette CPalette * pOldPalette = NULL; if( dcPaint.GetDeviceCaps(RASTERCAPS) & RC_PALETTE ) { pOldPalette = dcPaint.SelectPalette( &g_PaintManager->m_PaletteWide, FALSE ); dcPaint.RealizePalette(); } CExtMemoryDC mdc; if( bUseBackBuffer ) { mdc.__InitMemoryDC( &dcPaint, &rcClient, // &rcRealClient CExtMemoryDC::MDCOPT_TO_MEMORY |CExtMemoryDC::MDCOPT_FILL_SURFACE |CExtMemoryDC::MDCOPT_FORCE_DIB ); } CDC & dcDummyRef = mdc; CDC & dc = bUseBackBuffer ? dcDummyRef : dcPaint; CFont * pOldFont = (CFont *) dc.SelectObject( &g_PaintManager->m_FontNormal ); dc.FillSolidRect( &rcClient, g_PaintManager->GetMenuFrameFillColor() ); g_PaintManager->PaintMenuBorder( dc, rcClient, this ); ASSERT( !m_bExpandAvailable ); ASSERT( !m_bScrollingAvailable ); int nMenuBorderSize = g_PaintManager->GetMenuBorderSize(); int nMenuShadowSize = _GetPopupShadowSize(); // if( rcClient.left >= rcRealClient.left ) // { // CRect rcExcludePart(rcRealClient); // rcExcludePart.right = // rcClient.left + nMenuBorderSize; // dc.ExcludeClipRect( rcExcludePart ); // } // if( rcClient.right <= rcRealClient.right ) // { // CRect rcExcludePart(rcRealClient); // rcExcludePart.left = // rcClient.right - nMenuBorderSize; // dc.ExcludeClipRect( rcExcludePart ); // } if( rcClient.top >= rcRealClient.top ) { CRect rcExcludePart(rcRealClient); rcExcludePart.bottom = rcClient.top + nMenuBorderSize; dc.ExcludeClipRect( rcExcludePart ); } if( rcClient.bottom <= rcRealClient.bottom ) { CRect rcExcludePart(rcRealClient); rcExcludePart.top = rcClient.bottom - nMenuBorderSize; dc.ExcludeClipRect( rcExcludePart ); } // paint default color btn if( m_bEnableBtnColorDefault ) { bool bSelected = (m_nColorIdxCurr == IDX_DEFAULT_COLOR_BTN) ? true : false; CExtPaintManager::PAINTPUSHBUTTONDATA _ppbd( this, true, m_rcDefColorText, m_sBtnTextColorDefault, NULL, true, bSelected, false, // bSelected, false, true, bSelected, false, false, CExtPaintManager::__ALIGN_HORIZ_CENTER |CExtPaintManager::__ALIGN_VERT, NULL, false, 0, !bSelected ); g_PaintManager->PaintPushButton( dc, _ppbd ); CRect rcItem( m_rcDefColorText ); rcItem.OffsetRect( 0, rcItem.Height() + __EXT_MENU_GAP ); rcItem.bottom = rcItem.top + __EXT_MENU_SEPARATOR_HEIGHT; // g_PaintManager->PaintMenuSeparator( // dc, // rcItem, // false, // this // ); rcItem.top += rcItem.Height()/2; rcItem.bottom = rcItem.top+1; g_PaintManager->PaintSeparator( dc, rcItem, false, false, this ); } if( m_bEnableBtnColorCustom ) { bool bSelected = (m_nColorIdxCurr == IDX_CUSTOM_COLOR_BTN) ? true : false; CExtPaintManager::PAINTPUSHBUTTONDATA _ppbd( this, true, m_rcCustColorText, m_sBtnTextColorCustom, NULL, true, bSelected, false, // bSelected, false, true, bSelected, false, false, CExtPaintManager::__ALIGN_HORIZ_CENTER |CExtPaintManager::__ALIGN_VERT, NULL, false, 0, !bSelected ); g_PaintManager->PaintPushButton( dc, _ppbd ); CRect rcItem( m_rcCustColorText ); rcItem.OffsetRect( 0, - __EXT_MENU_GAP ); rcItem.bottom = rcItem.top; rcItem.top -= __EXT_MENU_SEPARATOR_HEIGHT; // g_PaintManager->PaintMenuSeparator( // dc, // rcItem, // false, // this // ); rcItem.top += rcItem.Height()/2; rcItem.bottom = rcItem.top+1; g_PaintManager->PaintSeparator( dc, rcItem, false, false, this ); } // paint color buttons COLORREF clrColorBorder = g_PaintManager->GetColor(COLOR_3DDKSHADOW); for( int nIdx = 0; nIdx < __NCLR_COUNT; nIdx++ ) { bool bSelected = (m_nColorIdxCurr == nIdx || m_nInitialColorIdx == nIdx ) ? true : false; CRect rcItem = _GetColorItemRect( nIdx ); CExtPaintManager::PAINTPUSHBUTTONDATA _ppbd( this, true, rcItem, _T(""), NULL, true, bSelected, bSelected, false, true, bSelected, false, false, CExtPaintManager::__ALIGN_HORIZ_CENTER |CExtPaintManager::__ALIGN_VERT, NULL, false, 0, !bSelected ); g_PaintManager->PaintPushButton( dc, _ppbd ); rcItem.DeflateRect( __NCLR_BOX_DX_SPACE, __NCLR_BOX_DY_SPACE ); dc.FillSolidRect( &rcItem, //dc.GetNearestColor( g_colors[nIdx].m_clr //) ); dc.Draw3dRect( &rcItem, clrColorBorder,clrColorBorder ); } if( m_nLeftAreaWidth > 0 ) { CRect rcLeftArea( rcClient ); rcLeftArea.right = rcLeftArea.left + m_nLeftAreaWidth; rcLeftArea.OffsetRect( nMenuBorderSize, 0 ); rcLeftArea.DeflateRect( 0, nMenuBorderSize ); DRAWLEFTAREADATA _DrawLeftAreaData( &dc, &rcLeftArea, this ); _DrawLeftAreaData.DoOwnerDrawPainting(); } CPoint point( 0, 0 ); ::GetCursorPos( &point ); ScreenToClient( &point ); dc.SelectClipRgn( NULL ); if( m_bCombineWithEA ) { ASSERT( m_eCombineAlign != __CMBA_NONE ); dc.SelectClipRgn(NULL); CRect rcExcludeClient( m_rcExcludeArea ); ScreenToClient( &rcExcludeClient ); g_PaintManager->PaintMenuCombinedArea( dc, rcExcludeClient, rcClient, m_eCombineAlign, this ); if( m_pCbPaintCombinedContent != NULL ) m_pCbPaintCombinedContent( m_pCbPaintCombinedCookie, dc, *this, m_rcExcludeArea, m_eCombineAlign ); } // if( m_bCombineWithEA ) dc.SelectObject( pOldFont ); if( bUseBackBuffer ) { ASSERT( mdc.GetSafeHdc() != NULL ); mdc.__Flush(); } if( _IsPopupWithShadows() && m_bAnimFinished && nMenuShadowSize > 0 ) { // if we need to paint shadow for client area (and combined exclude area) dcPaint.SelectClipRgn(NULL); CRect rcExcludeClient( 0,0,0,0 ), rcExcludeScreen( 0,0,0,0 ), rcBaseScreen( 0,0,0,0 ); if( m_bCombineWithEA ) { if( _IsPopupWithShadows() && m_bAnimFinished && nMenuShadowSize > 0 ) { // if we need to paint shadow for combined exclude area rcExcludeScreen = m_rcExcludeArea; rcExcludeClient = rcExcludeScreen; ScreenToClient( &rcExcludeClient ); dcPaint.ExcludeClipRect( &rcClient ); rcBaseScreen = rcClient; ClientToScreen( &rcBaseScreen ); VERIFY( m_ShadowCMBA.Paint( dcPaint, rcExcludeClient, rcExcludeScreen, rcBaseScreen, nMenuShadowSize ) ); dcPaint.SelectClipRgn(NULL); } // if we need to paint shadow for combined exclude area CRect rcExcludePart( m_rcExcludeArea ); ScreenToClient( &rcExcludePart ); dcPaint.ExcludeClipRect( &rcExcludePart ); } // if( m_bCombineWithEA ) VERIFY( m_ShadowMain.Paint( dcPaint, rcClient, rcBaseScreen, rcExcludeScreen, nMenuShadowSize ) ); } // if we need to paint shadow for client area (and combined exclude area) if( pOldPalette != NULL ) dcPaint.SelectPalette( pOldPalette, FALSE ); } int CExtPopupColorMenuWnd::_ColorItemHitTest( const CPoint & point ) { ASSERT_VALID( this ); for( int nIdx = 0; nIdx < __NCLR_COUNT; nIdx++ ) { CRect rcItem = _GetColorItemRect( nIdx ); if( rcItem.PtInRect(point) ) return nIdx; } if( m_rcDefColorText.PtInRect(point) ) return IDX_DEFAULT_COLOR_BTN; if( m_rcCustColorText.PtInRect(point) ) return IDX_CUSTOM_COLOR_BTN; return -1; } bool CExtPopupColorMenuWnd::_CanStartLevelTracking() { ASSERT_VALID( this ); if( _FindHelpMode() ) return false; if( _FindCustomizeMode() ) return false; return true; } bool CExtPopupColorMenuWnd::_OnMouseWheel( WPARAM wParam, LPARAM lParam, bool & bNoEat ) { ASSERT_VALID( this ); wParam; lParam; bNoEat; return true; } bool CExtPopupColorMenuWnd::_OnMouseMove( UINT nFlags, CPoint point, bool & bNoEat ) { ASSERT_VALID( this ); if( GetSafeHwnd() == NULL ) return false; if( GetSite().GetAnimated() != NULL ) return true; CPoint ptScreenClick( point ); ClientToScreen( &ptScreenClick ); HWND hWndFromPoint = ::WindowFromPoint( ptScreenClick ); if( hWndFromPoint != NULL && (::GetWindowLong(hWndFromPoint,GWL_STYLE)&WS_CHILD) != NULL && ::GetParent(hWndFromPoint) == m_hWnd ) { return false; // inplace edit } // ASSERT( GetCapture() == this ); /* CRect rectWindow; GetWindowRect( &rectWindow ); ScreenToClient( &rectWindow ); if( !rectWindow.PtInRect(point) ) */ if( !_PtInWndArea(point) ) { // _ItemFocusCancel( TRUE ); if( m_pWndParentMenu != NULL && m_pWndParentMenu->GetSafeHwnd() != NULL ) { ASSERT_VALID( m_pWndParentMenu ); ClientToScreen( &point ); m_pWndParentMenu->ScreenToClient( &point ); if( m_pWndParentMenu->_OnMouseMove( nFlags, point, bNoEat ) ) { if( bNoEat ) return false; _OnCancelMode(); return true; } } return false; } bool bHoverChanged = false; int nColorIdxCurr = _ColorItemHitTest(point); if( m_nColorIdxCurr != nColorIdxCurr ) { m_nColorIdxCurr = nColorIdxCurr; bHoverChanged = true; Invalidate(); if( m_nColorIdxCurr != IDX_CUSTOM_COLOR_BTN ) _NotifyColorChanged(); } if( m_nColorIdxCurr >= 0 ) { if( g_bMenuShowCoolTips && bHoverChanged ) { CExtSafeString sTipText = g_colors[m_nColorIdxCurr].m_sName; if( !sTipText.IsEmpty() && GetSite().GetCapture() == this && ( GetSite().GetAnimated() == NULL ) ) { CRect rcItem = _GetColorItemRect(m_nColorIdxCurr); ClientToScreen( &rcItem ); m_wndToolTip.SetText( sTipText ); VERIFY( m_wndToolTip.Show( this, rcItem ) ); } } // if( nOldCurIndex != nCurIndex ) } else _CoolTipHide(); return true; } bool CExtPopupColorMenuWnd::_OnMouseClick( UINT nFlags, CPoint point, bool & bNoEat ) { ASSERT_VALID( this ); bNoEat; if( GetSafeHwnd() == NULL ) return false; if( GetSite().GetAnimated() != NULL ) return true; bool bLButtonUpCall = (nFlags==WM_LBUTTONUP || nFlags==WM_NCLBUTTONUP) ? true : false; if( m_eCombineAlign != __CMBA_NONE && m_bTopLevel ) { CRect rcExcludeAreaTest( m_rcExcludeArea ); ScreenToClient( &rcExcludeAreaTest ); if( rcExcludeAreaTest.PtInRect( point ) ) { if( !bLButtonUpCall ) { _OnCancelMode(); return true; } return false; } // if( rcExcludeAreaTest.PtInRect( point ) ) } // if( m_eCombineAlign != __CMBA_NONE ... if( !bLButtonUpCall ) return false; nFlags; int m_nColorIdxCurr = _ColorItemHitTest(point); if( ( m_nColorIdxCurr >= 0 || m_nColorIdxCurr == IDX_DEFAULT_COLOR_BTN || m_nColorIdxCurr == IDX_CUSTOM_COLOR_BTN ) && ( ! _FindCustomizeMode() ) ) { _NotifyColorChanged( true ); g_SoundPlayer->PlaySound( CExtSoundPlayer::__ON_MENU_CMD_CLICKED ); } _EndSequence(); return true; } bool CExtPopupColorMenuWnd::_OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags, bool & bNoEat ) { ASSERT_VALID( this ); nRepCnt; nFlags; bNoEat; if( GetSafeHwnd() == NULL ) return true; //false; if( GetSite().GetAnimated() != NULL ) return true; bool bEat = false; //int nColorIdxCurr = m_nColorIdxCurr; switch( nChar ) { case VK_RETURN: { // if( m_pWndParentMenu == NULL ) // return true; // false; // int nParentCurIndex = // m_pWndParentMenu->_GetCurIndex(); // ASSERT( // nParentCurIndex >= 0 // && // nParentCurIndex <= // m_pWndParentMenu->ItemGetCount() // ); // m_pWndParentMenu->_ItemFocusCancel( // FALSE // ); // HWND hWndThis = GetSafeHwnd(); // CExtPopupMenuWnd::PassMsgLoop(); // if( !::IsWindow(hWndThis) ) // return false; // m_pWndParentMenu->_ItemFocusSet( // nParentCurIndex, // FALSE, // TRUE // ); if( ( m_nColorIdxCurr >= 0 || m_nColorIdxCurr == IDX_DEFAULT_COLOR_BTN || m_nColorIdxCurr == IDX_CUSTOM_COLOR_BTN ) && ( ! _FindCustomizeMode() ) ) { _NotifyColorChanged( true ); g_SoundPlayer->PlaySound( CExtSoundPlayer::__ON_MENU_CMD_CLICKED ); } _EndSequence(); return true; } // VK_RETURN case VK_MENU: case VK_ESCAPE: _EndSequence(); return true; case VK_RIGHT: bEat = true; if( m_nColorIdxCurr < 0 ) m_nColorIdxCurr = 0; else { CPoint ptCoord = _GetColorItemCoord(m_nColorIdxCurr); ptCoord.x++; if( ptCoord.x >= __NCLR_DX ) ptCoord.x = 0; m_nColorIdxCurr = ptCoord.x + ptCoord.y * __NCLR_DX; } break; case VK_LEFT: bEat = true; if( m_nColorIdxCurr < 0 ) m_nColorIdxCurr = 0; else { CPoint ptCoord = _GetColorItemCoord(m_nColorIdxCurr); ptCoord.x--; if( ptCoord.x < 0 ) ptCoord.x = __NCLR_DX - 1; m_nColorIdxCurr = ptCoord.x + ptCoord.y * __NCLR_DX; } break; case VK_DOWN: bEat = true; if( m_nColorIdxCurr < 0 ) m_nColorIdxCurr = 0; else { CPoint ptCoord = _GetColorItemCoord(m_nColorIdxCurr); ptCoord.y++; if( ptCoord.y >= __NCLR_DY ) ptCoord.y = 0; m_nColorIdxCurr = ptCoord.x + ptCoord.y * __NCLR_DX; } break; case VK_UP: bEat = true; if( m_nColorIdxCurr < 0 ) m_nColorIdxCurr = 0; else { CPoint ptCoord = _GetColorItemCoord(m_nColorIdxCurr); ptCoord.y--; if( ptCoord.y < 0 ) ptCoord.y = __NCLR_DY - 1; m_nColorIdxCurr = ptCoord.x + ptCoord.y * __NCLR_DX; } break; } // switch( nChar ) if( bEat ) { _CoolTipHide(); Invalidate(); _NotifyColorChanged(); } return bEat; } HWND CExtPopupColorMenuWnd::_GetWndNotifyColorChanged() { ASSERT_VALID( this ); if( m_hWndNotifyColorChanged != NULL ) { ASSERT( ::IsWindow(m_hWndNotifyColorChanged) ); return m_hWndNotifyColorChanged; } ASSERT( m_hWndCmdReciever != NULL ); ASSERT( ::IsWindow(m_hWndCmdReciever) ); return m_hWndCmdReciever; } void CExtPopupColorMenuWnd::_NotifyColorChanged( bool bFinal // = false ) { ASSERT_VALID( this ); HWND hWndNotify = _GetWndNotifyColorChanged(); ASSERT( hWndNotify != NULL ); ASSERT( ::IsWindow(hWndNotify) ); if( m_nColorIdxCurr == IDX_CUSTOM_COLOR_BTN ) { #if (!defined __EXT_MFC_NO_CUSTOMIZE) if( m_pNode != NULL ) { ASSERT_VALID( m_pNode ); CExtCustomizeSite * pSite = _FindCustomizeSite(); if( pSite != NULL && pSite->OnColorItemCustom( m_pNode ) ) return; } // if( m_pNode != NULL ) #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) ::PostMessage( hWndNotify, g_nMsgNotifyCustColor, 0, m_lParamCookie ); return; } COLORREF clr = RGB(0,0,0); if( m_nColorIdxCurr == IDX_DEFAULT_COLOR_BTN ) clr = m_clrDefault; else { if( m_nColorIdxCurr < 0 ) return; clr = g_colors[m_nColorIdxCurr].m_clr; } #if (!defined __EXT_MFC_NO_CUSTOMIZE) if( m_pNode != NULL ) { ASSERT_VALID( m_pNode ); CExtCustomizeSite * pSite = _FindCustomizeSite(); if( pSite != NULL && pSite->OnColorItemChanged( NULL, m_pNode, bFinal, clr, m_lParamCookie ) ) return; } // if( m_pNode != NULL ) #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) ::PostMessage( hWndNotify, bFinal ? g_nMsgNotifyColorChangedFinally : g_nMsgNotifyColorChanged , (WPARAM)clr, m_lParamCookie ); } int CExtPopupColorMenuWnd::_FindCellByColorRef(COLORREF clr) { ASSERT_VALID( this ); for( int nIdx = 0; nIdx < __NCLR_COUNT; nIdx++ ) { if( g_colors[nIdx].m_clr == clr ) return nIdx; } return -1; } #if (!defined __EXT_MFC_NO_CUSTOMIZE) // CExtCustomizeSite::ICustomizeDropTarget DROPEFFECT CExtPopupColorMenuWnd::OnCustomizeTargetOver( CExtCustomizeSite::CCmdDragInfo & _dragInfo, CPoint point, DWORD dwKeyState ) { ASSERT_VALID( this ); ASSERT( !_dragInfo.IsEmpty() ); _dragInfo; point; dwKeyState; return DROPEFFECT_NONE; } void CExtPopupColorMenuWnd::OnCustomizeTargetLeave() { ASSERT_VALID( this ); } bool CExtPopupColorMenuWnd::OnCustomizeTargetDrop( CExtCustomizeSite::CCmdDragInfo & _dragInfo, CPoint point, DROPEFFECT de ) { ASSERT_VALID( this ); ASSERT( !_dragInfo.IsEmpty() );; _dragInfo; point; de; return false; } // CExtCustomizeSite::ICustomizeDropSource void CExtPopupColorMenuWnd::OnCustomizeSourceDragComplete( DROPEFFECT de, bool bCanceled, bool * p_bNoResetActiveItem ) { ASSERT_VALID( this ); ASSERT( p_bNoResetActiveItem != NULL ); de; bCanceled; p_bNoResetActiveItem; } #endif // (!defined __EXT_MFC_NO_CUSTOMIZE) ///////////////////////////////////////////////////////////////////////////// // CExtPopupMenuWnd::CInPlaceEditWnd UINT CExtPopupMenuWnd::CInPlaceEditWnd::g_nMsgDeleteSelection = ::RegisterWindowMessage( _T("CExtPopupMenuWnd::CInPlaceEditWnd::g_nMsgDeleteSelection") ); UINT CExtPopupMenuWnd::CInPlaceEditWnd::g_nMsgSelectAll = ::RegisterWindowMessage( _T("CExtPopupMenuWnd::CInPlaceEditWnd::g_nMsgSelectAll") ); CExtPopupMenuWnd::CInPlaceEditWnd::CInPlaceEditWnd( CExtSafeString * pStr, CExtPopupMenuWnd::pCbVerifyTextInput pCbVerify, // = NULL CExtPopupMenuWnd::pCbPutTextInputResult pCbResult, // = NULL CExtPopupMenuWnd::pCbInplaceEditWndProc pCbWndProc, // = NULL LPVOID pCbCoockie // = NULL ) : m_pStr( pStr ) , m_pCbVerifyTextInput( pCbVerify ) , m_pCbPutTextInputResult( pCbResult ) , m_pCbWndProc( pCbWndProc ) , m_pCbCoockie( pCbCoockie ) , m_bNoCancelAtKillFocus( false ) { ASSERT( m_pStr != NULL ); } CExtPopupMenuWnd::CInPlaceEditWnd::~CInPlaceEditWnd() { } #ifdef _DEBUG void CExtPopupMenuWnd::CInPlaceEditWnd::AssertValid() const { CEdit::AssertValid(); ASSERT( m_pStr != NULL ); } #endif // _DEBUG bool CExtPopupMenuWnd::CInPlaceEditWnd::Create( CExtPopupMenuWnd * pPopup, CRect rc, UINT nDlgCtrlID ) { ASSERT_VALID( this ); ASSERT_VALID( pPopup ); ASSERT( pPopup->GetSafeHwnd() != NULL && ::IsWindow(pPopup->GetSafeHwnd()) ); m_bNoCancelAtKillFocus = false; m_sTextSaved = *m_pStr; if( ! CEdit::Create( WS_CHILD //|WS_VISIBLE |ES_LEFT|ES_AUTOHSCROLL, rc, pPopup, nDlgCtrlID ) ) { ASSERT( FALSE ); return false; } SetFont( &g_PaintManager->m_FontNormal ); SetWindowText( *m_pStr ); SetSel( 0, 0 ); return true; } LRESULT CExtPopupMenuWnd::CInPlaceEditWnd::WindowProc( UINT message, WPARAM wParam, LPARAM lParam ) { if( m_pCbWndProc != NULL ) { LRESULT lResult = 0L; if( m_pCbWndProc( lResult, message, wParam, lParam, *this, m_pCbCoockie ) ) return lResult; } // if( m_pCbWndProc != NULL ) if( message == WM_NCCALCSIZE ) { NCCALCSIZE_PARAMS * pNCCSP = reinterpret_cast < NCCALCSIZE_PARAMS * > ( lParam ); ASSERT( pNCCSP != NULL ); CRect rcInBarWnd( pNCCSP->rgrc[0] ); rcInBarWnd.DeflateRect( 2, 2, 0, 2 ); ::CopyRect( &(pNCCSP->rgrc[0]), rcInBarWnd ); return 0; } // if( message == WM_NCCALCSIZE ) if( message == WM_NCPAINT ) { CRect rcInBarWnd, rcInBarClient; GetWindowRect( &rcInBarWnd ); GetClientRect( &rcInBarClient ); ClientToScreen( &rcInBarClient ); if( rcInBarWnd == rcInBarClient ) return 0; CPoint ptDevOffset = -rcInBarWnd.TopLeft(); rcInBarWnd.OffsetRect( ptDevOffset ); rcInBarClient.OffsetRect( ptDevOffset ); CWindowDC dc( this ); ASSERT( dc.GetSafeHdc() != NULL ); dc.ExcludeClipRect( &rcInBarClient ); dc.FillSolidRect( rcInBarWnd, g_PaintManager->GetColor( COLOR_WINDOW ) ); return 0; } // if( message == WM_NCPAINT ) if( message == WM_GETDLGCODE ) return DLGC_WANTALLKEYS|DLGC_WANTCHARS|DLGC_WANTTAB; if( message == WM_RBUTTONDOWN || message == WM_RBUTTONUP || message == WM_RBUTTONDBLCLK || message == WM_CONTEXTMENU ) return 0; if( message == WM_KEYDOWN ) { ASSERT( m_pStr != NULL ); if( int(wParam) == VK_ESCAPE || int(wParam) == VK_MENU ) { // if( m_pCbVerifyTextInput != NULL ) // { // if( m_pCbVerifyTextInput( // *this, // m_pCbCoockie, // m_sTextSaved.IsEmpty() ? _T("") : ((LPCTSTR)m_sTextSaved), // m_sTextSaved.IsEmpty() ? _T("") : ((LPCTSTR)m_sTextSaved) // ) // ) // { // if( m_pCbPutTextInputResult != NULL ) // m_pCbPutTextInputResult( // *this, // m_pCbCoockie, // m_sTextSaved.IsEmpty() ? _T("") : ((LPCTSTR)m_sTextSaved) // ); // else // *m_pStr = m_sTextSaved; // } // } // if( m_pCbVerifyTextInput != NULL ) // else // { // if( m_pCbPutTextInputResult != NULL ) // m_pCbPutTextInputResult( // *this, // m_pCbCoockie, // m_sTextSaved.IsEmpty() ? _T("") : ((LPCTSTR)m_sTextSaved) // ); // else // *m_pStr = m_sTextSaved; // } // else from if( m_pCbVerifyTextInput != NULL ) if( int(wParam) == VK_MENU ) { GetPopupMenu()->PostMessage( WM_CANCELMODE ); return 0; } CExtPopupMenuWnd * pPopup = GetPopupMenu(); int nCurIndex = pPopup->_GetCurIndex(); ASSERT( 0 <= nCurIndex && nCurIndex < pPopup->ItemGetCount() ); pPopup->SetFocus(); pPopup->_ItemFocusCancel( FALSE ); pPopup->_ItemFocusSet( nCurIndex, FALSE, TRUE ); return 0; } // if( int(wParam) == VK_ESCAPE || int(wParam) == VK_MENU ) if( int(wParam) == VK_RETURN ) { ASSERT( m_pStr != NULL ); m_bNoCancelAtKillFocus = true; CString sText; GetWindowText( sText ); if( m_pCbVerifyTextInput != NULL ) { if( m_pCbVerifyTextInput( *this, m_pCbCoockie, sText.IsEmpty() ? _T("") : ((LPCTSTR)sText), sText.IsEmpty() ? _T("") : ((LPCTSTR)sText) ) ) { if( m_pCbPutTextInputResult != NULL ) m_pCbPutTextInputResult( *this, m_pCbCoockie, sText.IsEmpty() ? _T("") : ((LPCTSTR)sText) ); else *m_pStr = sText; } } // if( m_pCbVerifyTextInput != NULL ) else { if( m_pCbPutTextInputResult != NULL ) m_pCbPutTextInputResult( *this, m_pCbCoockie, sText.IsEmpty() ? _T("") : ((LPCTSTR)sText) ); else *m_pStr = sText; } // else from if( m_pCbVerifyTextInput != NULL ) CExtPopupMenuWnd * pPopup = GetPopupMenu(); int nCurIndex = pPopup->_GetCurIndex(); ASSERT( 0 <= nCurIndex && nCurIndex < pPopup->ItemGetCount() ); pPopup->SetFocus(); pPopup->_ItemFocusCancel( FALSE ); pPopup->_ItemFocusSet( nCurIndex, FALSE, TRUE ); return 0; } // if( int(wParam) == VK_RETURN ) bool bAlt = ( (::GetAsyncKeyState(VK_MENU)&0x8000) != 0 ) ? true : false; if( bAlt ) { GetPopupMenu()->PostMessage( WM_CANCELMODE ); return 0; } ASSERT( m_pStr != NULL ); CString sTextOld; GetWindowText( sTextOld ); DWORD dwSelSaved = CEdit::GetSel(); CEdit::SetRedraw( FALSE ); LRESULT lResult = CEdit::WindowProc( message, wParam, lParam ); CString sTextNew; GetWindowText( sTextNew ); if( m_pCbVerifyTextInput != NULL ) { if( m_pCbVerifyTextInput( *this, m_pCbCoockie, sTextOld.IsEmpty() ? _T("") : ((LPCTSTR)sTextOld), sTextNew.IsEmpty() ? _T("") : ((LPCTSTR)sTextNew) ) ) { //*m_pStr = sTextNew; } else { CEdit::SetSel( 0, -1 ); CEdit::ReplaceSel( sTextOld ); CEdit::SetSel( dwSelSaved ); } } // if( m_pCbVerifyTextInput != NULL ) //else //*m_pStr = sTextNew; CEdit::SetRedraw( TRUE ); Invalidate(); UpdateWindow(); return lResult; } // if( message == WM_KEYDOWN ) else if( message == WM_CHAR ) { ASSERT( m_pStr != NULL ); CString sTextOld; GetWindowText( sTextOld ); DWORD dwSelSaved = CEdit::GetSel(); CEdit::SetRedraw( FALSE ); LRESULT lResult = CEdit::WindowProc( message, wParam, lParam ); CString sTextNew; GetWindowText( sTextNew ); if( m_pCbVerifyTextInput != NULL ) { if( m_pCbVerifyTextInput( *this, m_pCbCoockie, sTextOld.IsEmpty() ? _T("") : ((LPCTSTR)sTextOld), sTextNew.IsEmpty() ? _T("") : ((LPCTSTR)sTextNew) ) ) { //*m_pStr = sTextNew; } else { CEdit::SetSel( 0, -1 ); CEdit::ReplaceSel( sTextOld ); CEdit::SetSel( dwSelSaved ); } } // if( m_pCbVerifyTextInput != NULL ) //else //*m_pStr = sTextNew; CEdit::SetRedraw( TRUE ); Invalidate(); UpdateWindow(); return lResult; } // else if( message == WM_CHAR ) else if( message == CExtPopupMenuWnd::CInPlaceEditWnd::g_nMsgDeleteSelection ) { int nChrStart = 0, nChrEnd = 0; CEdit::GetSel( nChrStart, nChrEnd ); if( nChrStart != nChrEnd ) CEdit::ReplaceSel( _T("") ); else { nChrEnd = nChrStart + 1; SetRedraw( FALSE ); SetSel( nChrStart, nChrEnd ); CEdit::ReplaceSel( _T("") ); SetSel( nChrStart, nChrStart ); SetRedraw( TRUE ); Invalidate(); } // else from if( nChrStart != nChrEnd ) return 0; } // else if( message == CExtPopupMenuWnd::CInPlaceEditWnd::g_nMsgDeleteSelection ) else if( message == CExtPopupMenuWnd::CInPlaceEditWnd::g_nMsgSelectAll ) { CEdit::SetSel( 0, -1 ); return 0; } // else if( message == CExtPopupMenuWnd::CInPlaceEditWnd::g_nMsgSelectAll ) else if( message == WM_KILLFOCUS ) { ASSERT( m_pStr != NULL ); ShowWindow( SW_HIDE ); if( !m_bNoCancelAtKillFocus ) SetWindowText( *m_pStr ); // ASSERT( m_pStr != NULL ); // CString sText; // if( m_bNoCancelAtKillFocus ) // GetWindowText( sText ); // else // sText = (LPCTSTR)m_sTextSaved; // if( m_pCbVerifyTextInput != NULL ) // { // if( m_pCbVerifyTextInput( // *this, // m_pCbCoockie, // sText.IsEmpty() ? _T("") : ((LPCTSTR)sText), // sText.IsEmpty() ? _T("") : ((LPCTSTR)sText) // ) // ) // { // if( m_pCbPutTextInputResult != NULL ) // m_pCbPutTextInputResult( // *this, // m_pCbCoockie, // sText.IsEmpty() ? _T("") : ((LPCTSTR)sText) // ); // else // *m_pStr = sText; // } // } // if( m_pCbVerifyTextInput != NULL ) // else // { // if( m_pCbPutTextInputResult != NULL ) // m_pCbPutTextInputResult( // *this, // m_pCbCoockie, // sText.IsEmpty() ? _T("") : ((LPCTSTR)sText) // ); // else // *m_pStr = sText; // } // else from if( m_pCbVerifyTextInput != NULL ) } // else if( message == WM_KILLFOCUS ) return CEdit::WindowProc( message, wParam, lParam ); } void CExtPopupMenuWnd::CInPlaceEditWnd::PostNcDestroy() { ASSERT_VALID( this ); delete this; } CExtPopupMenuWnd * CExtPopupMenuWnd::CInPlaceEditWnd::GetPopupMenu() { ASSERT_VALID( this ); ASSERT( GetSafeHwnd() != NULL && ::IsWindow(GetSafeHwnd()) ); CWnd * pWndParent = GetParent(); ASSERT_VALID( pWndParent ); ASSERT_KINDOF( CExtPopupMenuWnd, pWndParent ); ASSERT( pWndParent->GetSafeHwnd() != NULL && ::IsWindow(pWndParent->GetSafeHwnd()) ); return STATIC_DOWNCAST( CExtPopupMenuWnd, pWndParent ); }